Ninject Multicasting

时间:2011-10-31 21:01:53

标签: c# c#-4.0 dependency-injection ninject

我希望绑定服务的多个实现,并立即调用所有这些实现:

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 个答案:

答案 0 :(得分: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 { }

输出:

  


  垃圾邮件
  更多垃圾邮件

答案 1 :(得分:0)

你不能将许多具体的类绑定到一个单独的接口,这是违反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());