Ninject Multicasting - PullRequest
       12

Ninject Multicasting

8 голосов
/ 01 ноября 2011

Я хочу связать несколько реализаций службы и сделать так, чтобы все они вызывались одновременно:

var kernel = new StandardKernel();

kernel.Bind<IBreakfast>.To<Spam>();
kernel.Bind<IBreakfast>.To<Eggs>();
kernel.Bind<IBreakfast>.To<MoreSpam>();

kernel.Get<IBreakfast>().Eat();   // call Eat method on all three bound implementations

Ninject не нравится, и выдает исключение из-за наличия нескольких привязок.Есть ли способ, которым я могу обойти эту ошибку, и чтобы все реализации назывались?

Кроме того, вызовы Bind<> могут быть в разных проектах, которые могут загружаться или не загружаться во время выполнения, поэтому созданиеотдельная реализация для их вызова не будет работать.Это часть архитектуры подключаемого модуля для веб-сайта ASP.NET MVC 3.

Ответы [ 2 ]

13 голосов
/ 01 ноября 2011

Если вы используете инжектор конструктора и у вас есть параметр List<IBreakfast>, Ninject создаст список, используя все ваши привязки.Затем вы можете вызвать Eat в этих случаях.

Вы можете использовать этот шаблон, чтобы Ninject создал список ваших плагинов, например.

    [Test]
    public void Test()
    {
        IKernel kernel = new StandardKernel();

        kernel.Bind<IBreakfast>().To<Eggs>();
        kernel.Bind<IBreakfast>().To<Spam>();
        kernel.Bind<IBreakfast>().To<MoreSpam>();

        var bling = kernel.Get<Bling>();
    }

    private class Bling
    {
        public Bling(List<IBreakfast> things)
        {
            things.ForEach(t => t.Eat());
        }
    }

    private interface IBreakfast
    {
        void Eat();
    }

    private class Ingrediant : IBreakfast
    {
        public void Eat(){Console.WriteLine(GetType().Name);}
    }

    private class Eggs : Ingrediant{}
    private class Spam : Ingrediant{}
    private class MoreSpam : Ingrediant { }

Выход:

Яйца
Спам
БольшеСпама

0 голосов
/ 01 ноября 2011

Вы не можете привязать множество конкретных классов к одному интерфейсу, что противоречит правилам DI.

В основном вы хотите инициализировать пару конкретных экземпляров и вызвать их метод.

Вы можете проверить это:

Bind<IBreakfast>.To<Spam>().Named("Spam");
Bind<IBreakfast>.To<Eggs>().Named("Eggs");
Bind<IBreakfast>.To<MoreSpam>().Named("MoreSpam");

var breakfastList = new List() { "Spam", "Eggs", "MoreSpam" };
breakfastList.ForEach(item => kernel.Get<IBreakfast>(item).Eat());
...