0

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.

Zoltán Tamási
  • 12,249
  • 8
  • 65
  • 93

2 Answers2

1

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());
Community
  • 1
  • 1
BatteryBackupUnit
  • 12,934
  • 1
  • 42
  • 68
0

I'm not sure if I got your question correctly. Isn't it that you have to bind IFoo to your concrete type?

     kernel = new StandardKernel();
     kernel.Bind(typeof(IFoo)).To<Class2>();
     kernel.Bind<IFooFactoryWithType>().ToFactory();
     var createdInstance = kernel.Get<IFooFactoryWithType>().Create(typeof(IFoo));
Tom Ash
  • 158
  • 11
  • In this case no, because there are more concrete types which I request at runtime. I wanted to delegate the request to Ninject with such a factory. – Zoltán Tamási Feb 17 '16 at 07:09