2010-11-22 41 views
1

鑑於具體的類,並具有名稱的接口不匹配StructureMap配置具體類,其接口名稱不匹配

Harvester_JohnDeere_Parsley : AbstractMachine, IParsleyHarvester 
Harvester_NewHolland_Sage : AbstractMachine, ISageHarvester 
Harvester_Kubota_Rosemary : AbstractMachine, IRosemaryHarvester 

在接口都有一個共同的父

IParsleyHarvester : ISpiceHarvester 
ISageHarvester : ISpiceHarvester 
IRosemaryHarvester : ISpiceHarvester 

如何StructureMap被配置以便我的實例...收割機可以注入到構造函數中,例如

public ParsleyField(IParsleyHarvester parsleyHarvester) 

而不必在註冊表中單獨配置每對;例如

For<ISageHarvester>().Use<Harvester_NewHolland_Sage>(); 

我試過掃描

Scan(x => 
{ 
    x.AssemblyContainingType<Harvester_Kubota_Rosemary>(); 
    x.AddAllTypesOf<ISpiceHarvester>(); 

但我...收割機接口不被映射。

謝謝!

編輯

這兩個答案的工作。 @ jeroenh的優點是可以添加guard子句來排除類(無論出於何種原因)。下面是一個基於@ Mac對this question的回答的例子。

public class HarvesterConvention : StructureMap.Graph.IRegistrationConvention 
{ 
    public void Process(Type type, Registry registry) 
    { 
     // only interested in non abstract concrete types 
     if (type.IsAbstract || !type.IsClass) 
      return; 

     // Get interface 
     var interfaceType = type.GetInterface(
      "I" + type.Name.Split('_').Last() + "Harvester"); 

     if (interfaceType == null) 
      throw new ArgumentNullException(
       "type", 
       type.Name+" should implement "+interfaceType); 

     // register (can use AddType overload method to create named types 
     registry.AddType(interfaceType, type); 
    } 
} 

用法:

Scan(x => 
{ 
    x.AssemblyContainingType<Harvester_Kubota_Rosemary>(); 
    x.Convention<HarvesterConvention>(); 
    x.AddAllTypesOf<ISpiceHarvester>(); 

回答

1

StructureMap不知道你的約定。您需要通過添加自定義註冊約定來告訴它。實現IRegistrationConvention接口,約定添加到組裝掃描儀:

Scan(x => 
    { 
    x.Convention<MyConvention>(); 
    } 
1

我改編自@ Kirschstein的回答解決this question

Scan(x => 
{ 
    x.AssemblyContainingType<Harvester_Kubota_Rosemary>(); 
    x.AddAllTypesOf<ISpiceHarvester>() 
    .NameBy(type => "I" + type.Name.Split('_').Last() + "Harvester"); 

定義將具體類的名稱轉換爲其接口名稱以進行查找的方式。