Ninject Multicasting

删除回忆录丶 提交于 2019-12-06 23:11:17

问题


I want to bind multiple implementations of a service and have all of them called at once:

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 doesn't like that, and will throw an exception about having multiple bindings. Is there a way I can get around that error, and have all the implementations called?

Also, the Bind<> calls can be in different projects which may or may not be loaded at run-time, so creating a single implementation to call them won't work. This is part of a plug-in architecture for an ASP.NET MVC 3 web site.


回答1:


If you use constructor injection and have a List<IBreakfast> parameter, then Ninject will construct a list using all your bindings. You can then call Eat on these instances.

You can use this pattern to get Ninject to create a list of your plugins for instance.

    [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 { }

Output:

Eggs
Spam
MoreSpam




回答2:


You can't bind many concrete classes to once single interface, that's against DI rules.

What basically you want to do is, initialize couple of concrete instances and call their method.

You may want to check this out:

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


来源:https://stackoverflow.com/questions/7959709/ninject-multicasting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!