Разрешить регистрацию имен из Unity, которая создает контроллер

Я работаю над веб-API ASP.NET, который содержит несколько контроллеров веб-API. Каждый контроллер имеет зависимость от IMessageSender.

public class OrderController: ApiController {
    private readonly IMessageSender _msgSender;
    public OrderController(IMessageSender msgSender) {
        _msgSender = msSender;
    }
}

У меня есть 3 разных реализации IMessageSender — CloudMessageSender, InMemoryMessageSender и NServiceBusMessageSender.

public class CloudMessageSender: IMessageSender 
{
}
public class InMemoryMessageSender: IMessageSender 
{
}
public class NServiceBusMessageSender: IMessageSender 
{
}

Я использую Unity и Unity.WebApi для разрешения зависимостей и зарегистрировал 3 именованных регистрации IMessageSender.

container.RegisterType<IMessageSender, CloudMessageSender>("res-cloud");
container.RegisterType<IMessageSender, InMemoryMessageSender>("res-inmem");
container.RegisterType<IMessageSender, NServiceBusMessageSender>("res-nsvc");

Проблема, с которой я столкнулся, заключается в том, что для разных контроллеров мне нужно использовать другую реализацию IMessageSender. Бывший. OrdersController нужно использовать CloudMessageSender, а CustomersController нужно использовать InMemoryMessageSender. По умолчанию Unity внедрит либо безымянное разрешение, либо (в моем случае) первое.

Как я могу указать или контролировать, какой контроллер должен быть внедрен с какой реализацией IMessageSender?


person Pratik Bhattacharya    schedule 16.02.2017    source источник
comment
stackoverflow.com/questions/18665324/   -  person Chetan Ranpariya    schedule 16.02.2017
comment
Когда вы начнете использовать именованные регистрации, лучше переключиться на Pure DI. Дополнительные сведения см. в этой статье: criticalsoftwareblog.com/index.php/2015/08/23/   -  person Yacoub Massad    schedule 16.02.2017


Ответы (1)


Вы также можете настроить контейнер для регистрации типа контроллера с членами инъекции. В списке членов инъекции вы можете разрешить уже зарегистрированные зависимости по имени. Таким образом, будет обеспечено разрешение правильного типа при создании экземпляра контроллера.

container.RegisterType<IMessageSender, CloudMessageSender>("res-cloud");
container.RegisterType<IMessageSender, InMemoryMessageSender>("res-inmem");
container.RegisterType<IMessageSender, NServiceBusMessageSender>("res-nsvc");

var messageSender = new ResolvedParameter<IMessageService>("res-cloud");
container.RegisterType<OrderController>(new InjectionConstructor(messageSender));

Теперь при инициализации экземпляра OrderController тип аргумента msgSender будет преобразован в CloudMessageSender.

Одна проблема с этим способом регистрации контроллера заключается в том, что вам нужно разрешить и передать все параметры конструктора контроллера.

Unity не поддерживает разрешение типов на основе имени без использования этого подхода.

person Chetan Ranpariya    schedule 16.02.2017
comment
Unity не поддерживает разрешение типов на основе имени без использования этого подхода. - это веская причина не использовать Unity. Другое дело, что у него не было обновлений несколько лет. - person NightOwl888; 16.02.2017
comment
Ну, использовать его или нет, зависит от конкретного случая. Использование модуля с MVC упрощает настройку и настройку по сравнению с другими, такими как Castle Windsor. Согласитесь, что Unity должны были обновить себя, чтобы соответствовать контейнерам IoC. - person Chetan Ranpariya; 16.02.2017