Ninject Multicasting

Mik*_*att 8 c# dependency-injection ninject c#-4.0

我想绑定一个服务的多个实现,并立即调用它们:

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
Run Code Online (Sandbox Code Playgroud)

Ninject不喜欢这样,并且会抛出有关多个绑定的异常.有没有办法解决这个错误,并调用所有实现?

此外,Bind<>调用可以在不同的项目中,这些项目可能在运行时加载,也可能不加载,因此创建单个实现来调用它们将不起作用.这是ASP.NET MVC 3网站的插件体系结构的一部分.

Tim*_*oyd 13

如果你使用构造函数注入并有一个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 { }
Run Code Online (Sandbox Code Playgroud)

输出:

鸡蛋
垃圾邮件
更多 垃圾邮件

  • @MikeWyatt:不,多个`Bind`s很好.什么是不好的是一个`Get <T>`产生的不仅仅是'Single`项.如果你想这样做,你可以使用`GetAll <T>`(或者使用通过`List <T>`,`T []`或`IEnumerable <T>`隐式批量多次注册(如建议的那样)(发布/代码作为测试的人不会发布爆炸的东西!).请注意,Ninject没有任何muchanismt来生成隐式Composite,以按您希望的方式组播调用. (5认同)