Reputation: 1170
I have 2 different concrete objects, lets save ConcreteOne and ConcreteTwo. Each of these implement an interface ILooseyGoosey. I would like ninject to call a different method depending on the attribute on that method.
This is what I have so far:
public class ConcreteOne : ILooseyGoosey
{
public void SomeMethod() { };
}
public class ConcreteTwo : ILooseyGoosey
{
public void SomeMethod() { } ;
}
public interface ILooseyGoosey
{
[CallConcreteTwo()]
void SomeMethod();
}
This is what I have defined in my Ninject module:
public override void Load()
{
Bind<ILooseyGoosey>().To<ConcreteOne>().InjectMethodsWhere(mi => mi.GetCustomAttributes(true).Where(a => a.GetType() == typeof(CallConcreteTwoAttribute)).Count() == 0);
Bind<ILooseyGoosey>().To<ConcreteTwo>().InjectMethodsWhere(mi => mi.GetCustomAttributes(true).Where(a => a.GetType() == typeof(CallConcreteTwoAttribute)).Count() > 0);
}
I get the error of:
System.NotSupportedException : Error registering service ILooseyGoosey: Multiple default bindings declared for service. Found 2 default bindings:
Upvotes: 1
Views: 2142
Reputation: 3236
Not written by me. Please see: http://www.ninject.org/wiki.html
Ninject Download it Extensions Contribute Visit the Dojo Speak up Sponsors Merchandise Version: »Ninject »MVC3 Multi injectionEdit PagePage History Ninject allows you to inject multiple objects bound to a particular type or interface. For example, if we have our IWeapon interface, and two implementations, Sword and Dagger: public interface IWeapon { string Hit(string target); } public class Sword : IWeapon { public string Hit(string target) { return "Slice " + target + " in half"; } } public class Dagger : IWeapon { public string Hit(string target) { return "Stab " + target + " to death"; } } Here we have the Samurai class. You can see that its constructor takes an array of IWeapon. public class Samurai { readonly IEnumerable allWeapons; public Samurai(IWeapon[] allWeapons) { this.allWeapons = allWeapons; } public void Attack(string target) { foreach (IWeapon weapon in this.allWeapons) Console.WriteLine(weapon.Hit(target)); } } We can create bindings from the IWeapon interface to the Sword and Dagger types. class TestModule : Ninject.Modules.NinjectModule { public override void Load() { Bind().To(); Bind().To(); } } Finally, a kernel is created with the module we defined above. We ask Ninject for an instance of a Samurai. Now, when you ask the Samurai to attack, you will see it has been given an array of all the types bound to IWeapon. class Program { public static void Main() { Ninject.IKernel kernel = new StandardKernel(new TestModule()); var samurai = kernel.Get(); samurai.Attack("your enemy"); } } And you’ll see: Stab your enemy to death Slice your enemy in half The kernel also exposes a GetAll method which lets you generate the same output by doing: class Program { public static void Main() { Ninject.IKernel kernel = new StandardKernel(new TestModule()); IEnumerable weapons = kernel.GetAll(); foreach(var weapon in weapons) Console.WriteLine(weapon.Hit("the evildoers")); } } Continue reading: Object Scopes Enkari Ninject is the illegitimate brainchild of Nate Kohari. Copyright ©2007-2012 Enkari, Ltd and the Ninject project contributors.
Upvotes: 1
Reputation: 1554
Not sure if you still need the answer, meta data based approach is the way to go. You'd want to bind in the meta data way in Ninject 2.0. Refer Contextual bindings with Ninject 2.0
Upvotes: 1
Reputation: 3868
The problem is that you are assigning one interface to two implementations without any conditional logic. The logic you are applying is only applied to which methods are injected. Ninject has no idea which binding to use since you are indicating that they are both default.
Upvotes: 1