2010-11-22 3 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 быть сконфигурирован так, чтобы экземпляры I ... Harvester можно вводить в конструктор, например

public ParsleyField(IParsleyHarvester parsleyHarvester) 

без необходимости индивидуальной настройки каждой пары в реестре? например

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

Я пытался сканирования

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

но я ... интерфейсы Harvester не получают карту.

Спасибо!

редактировать:

Оба ответа работают. @ jeroenh's имеет то преимущество, что кластеры безопасности могут быть добавлены для исключения классов (по какой-либо причине). Вот пример, основанный на ответе @ 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"); 

Определяет способ преобразования имени конкретного класса в его имя интерфейса для поисковых целей.

Смежные вопросы