StructureMap настраивает конкретные классы, чьи имена интерфейсов не совпадают - PullRequest
1 голос
/ 23 ноября 2010

Учитывая конкретные классы и интерфейсы, имена которых не совпадают

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

, где интерфейсы имеют общего родителя

IParsleyHarvester : ISpiceHarvester
ISageHarvester : ISpiceHarvester
IRosemaryHarvester : ISpiceHarvester

, как можно настроить StructureMap так, чтобы экземпляры I... Харвестер может быть введен в конструктор, например,

public ParsleyField(IParsleyHarvester parsleyHarvester)

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

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

Я пробовал сканировать

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

, но интерфейсы харвестера I ... не отображаются.

Спасибо!

edit :

Оба ответа работают.Преимущество @ jeroenh заключается в том, что для исключения классов (по любой причине) могут быть добавлены охранные предложения.Вот пример, основанный на ответе @ Mac на этот вопрос .

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>();

Ответы [ 2 ]

1 голос
/ 23 ноября 2010

Я адаптировал решение из ответа @ Киршштейна на этот вопрос .

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

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

1 голос
/ 23 ноября 2010

StructureMap не знает о вашем соглашении.Вы должны сообщить об этом, добавив пользовательское соглашение о регистрации.Реализуйте интерфейс IRegistrationConvention и добавьте соглашение в сканер сборки:

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