Внедрение нескольких параметров конструктора одного типа с помощью Ninject 2.0 - PullRequest
11 голосов
/ 02 ноября 2011

Я использую Ninject 2.0 для обработки DI в одном из моих приложений, и я столкнулся с чем-то, что меня смущает. Если честно, отсутствие документации не слишком помогает.

Скажем, у меня есть конструктор с подписью -

ctor(IServiceFactory factory1, IServiceFactory factory2)
{
    this.factory1 = factory1;
    this.factory2 = factory2;
}

Хотя эти две службы реализуют один и тот же интерфейс, они являются совершенно разными реализациями и используются в разное время, поэтому я не хочу внедрять IEnumerable<IServiceFactory>.

У меня вопрос: когда я связываю экземпляры, как мне сказать Ninject, что вводить для каждого?

Заранее спасибо.

Обновление

Ради того, кто захочет увидеть код, в конечном итоге после прочтения ссылок Ремо ... Вот вкратце. (Я никогда не понимал, что C # имеет атрибуты параметров!)

//abstract factory
public interface IServiceFactory
{
    Service Create();
}

//concrete factories
public class Service1Factory : IServiceFactory
{
    public IService Create()
    {
        return new Service1();
    }
}

public class Service2Factory : IServiceFactory
{
    public IService Create()
    {
        return new Service2();
    }
}

//Binding Module (in composition root)
public class ServiceFactoryModule : NinjectModule
{
    public override void Load()
    {
        Bind<IServiceFactory>()
            .To<Service1Factory>()
            .Named("Service1");

        Bind<IServiceFactory>()
            .To<Service2Factory>()
            .Named("Service2");
    }
}

//consumer of bindings
public class Consumer(
    [Named("Service1")] service1Factory,
    [Named("Service2")] service2Factory)
{
}

1 Ответ

10 голосов
/ 02 ноября 2011

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

Если вы решите остаться с тем же интерфейсом, чем использовать условные привязки.См. Документацию о том, как это сделать:

https://github.com/ninject/ninject/wiki/Contextual-Binding

https://github.com/ninject/ninject/wiki/Conventions-Based-Binding

...