2011-06-20 94 views

回答

3

據我知道你需要創建在StructureMap.Graph命名空間中找到一個自定義IRegistrationConvention

執行公約

public class ServiceDiscoveryConvention 
           : StructureMap.Graph.IRegistrationConvention 
{ 
    public void Process(Type type, Registry registry) 
    { 
     // check if type has attribute 
     // add to registry using the registry variable 
    } 
} 

公約添加到掃描儀

Scan(cfg => 
     { 
      cfg.TheCallingAssembly(); // or whatever assemblies you are scanning 
      cfg.Convention<ServiceAttributeConvention>(); 
     }); 

備註

如果你有時間你的決定,你可能想使用接口而不是a ttributes。使用界面,您可以爲所有類提供通用合同,並且在項目增長時更容易處理。

屬性有遍佈整個代碼的傾向,重構它們可能是一個真正的痛苦。接口在重構時有更好的工具支持。

我使用的接口,類似的任務(插件系統),如

public class TypeScanner<T> : IRegistrationConvention 
{ 
    private static readonly Type PluginInterface = typeof(T); 

    public void Process(Type type, Registry registry) 
    { 
     if (type.IsAbstract || type.BaseType == null) return; 
     if (PluginInterface.IsAssignableFrom(type) == false) return; 

     registry.For(PluginInterface).Singleton().Add(instance); 
    } 
} 

使用公約將是類似的:

Scan(cfg => 
     { 
      cfg.TheCallingAssembly(); // or whatever assemblies you are scanning 
      cfg.Convention<TypeScanner<IYourService>>(); 
     }); 

如果你的約定需要構造函數的參數,你可以使用With

Scan(cfg => 
     { 
      cfg.TheCallingAssembly(); // or whatever assemblies you are scanning 
      var convention = new SomeConvention(x,y,z); 
      cfg.With(convention); 
     }); 
+0

公約是偉大的。只是儘量不要讓它太神奇。你爲它命名的方式使得知道該公約中發生的事情變得非常直觀,但我以抽象的名義看到了一些非常可怕的事情。 –

+0

@Zebi,謝謝!我會稍後再試 – theateist

+0

@Nathan,你能解釋一下嗎? – theateist

2

沒有必要使用StructureMap註冊類型if你不會通過接口來檢索它。

考慮:

[Service] 
public class A {} 

[Service] 
public class B {} 

下面的代碼將工作得很好,和StructureMap將填充在A或B的任何構造函數依賴,沒有任何特殊登記:

var instanceA = ObjectFactory.GetInstance<A>(); 
var instanceB = ObjectFactory.GetInstance<B>(); 
相關問題