问题
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