I have the following classes:
using System;
interface IA { }
class A1 : IA { }
class A2 : IA { }
class B
{
public B(IA a) {}
}
class BProvider : Provider<B>
{
IA _a;
public BProvider(IA a) { _a=a; }
protected override B CreateInstance(IContext context) { return new B(_a); }
}
ninject module Load() code:
Bind<IA>().To<A1>();
Bind<IA>().To<A2>();
Bind<B>().ToProvider<BProvider>();
main code:
kernel.GetAll<IA>(); // works fine
kernel.GetAll<B>(); // I expect to get IEnumerable<B> with two elements, but instead of this I get an error that there are multiple bindings of IA and ninject cannot determine which to use
So the question is if I can make the last statement work as expected or do it some other way?
It will throw that exception because Ninject will need to create an instance of object of type BProvider
. To do it, it has to fill in the dependency on IA
. But moment... there are two bindings on IA
, which one should I choose?....
You can use some conditional binding to decide which implementation should be used.
One way is with NamedAttribute
:
Bind<IA>().To<A1>();
Bind<IA>().To<A2>().Named("SecondImpl");
Bind<B>().ToProvider<BProvider>();
class BProvider : Provider<B>
{
IA _a;
public BProvider([Named("SecondImpl")]IA a) { _a=a; }
protected override B CreateInstance(IContext context) { return new B(_a); }
}
In this case A1 will be injected as default where NamedAttribute
is not specified.
or like @Remo Gloor explains in this post: Configuring Ninject
Bind<IA>().To<A1>();
Bind<IA>().To<A2>().WhenParentNamed("NeedSecondImpl");
Bind<B>().ToProvider<BProvider>().Named("NeedSecondImpl");
This is bit cleaner, because you dont have to tie your code to Ninject and can just let it on configuration (in one place).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With