I know I can bind the following generic interface with ToFactory
method.
public interface IFoo {}
public interface IFooFactory {
TFoo Create<TFoo>() where TFoo : IFoo;
}
...
kernel.Bind<IFooFactory>().ToFactory();
This code works as expected. However, if I want to use a non-generic variant, I get a Ninject activation exception because it searches for binding of IFoo
, and so it seems that the factory extension does not recognize the Type
argument.
public interface IFooFactoryWithType {
IFoo Create(Type concreteType);
}
...
kernel.Bind<IFooFactoryWithType>().ToFactory();
Am I doing something wrong, or is it not supported this way? In my current scenario I cannot use generic version because the type is coming from a runtime parameter. I could use some reflection hack with MakeGenericMethod
and friends of course but I'd like to avoid that.
This is not supported out of the box. But you can exchange the IInstanceProvider
with a custom implementation by doing:
kernel.Bind<IFooFactory>()
.ToFactory(() => new MyCustomInstanceProvider());
Also see the wiki for more information.
Furthermore Ninject factory create T based on enum could be of interested to you.
your IInstanceProvider
implementation could look like that (i haven't tested whether it actually compiles, sorry):
internal class TypeDefinedByArgumentInstanceProvider : StandardInstanceProvider
{
protected override Type GetType(MethodInfo methodInfo, object[] arguments)
{
return (Type)arguments.Single();
}
}
kernel.Bind<IFooFactory>()
.ToFactory(() => new TypeDefinedByArgumentInstanceProvider());