2016-02-16 135 views
0

我知道我可以将以下通用接口与ToFactory方法绑定。Ninject.Extensions.Factory与非泛型类型参数

public interface IFoo {} 
public interface IFooFactory { 
    TFoo Create<TFoo>() where TFoo : IFoo; 
} 

... 

kernel.Bind<IFooFactory>().ToFactory(); 

此代码按预期工作。但是,如果我想使用非泛型变体,则会收到Ninject激活异常,因为它搜索IFoo的绑定,所以看起来工厂扩展不能识别Type参数。

public interface IFooFactoryWithType { 
    IFoo Create(Type concreteType); 
} 

... 

kernel.Bind<IFooFactoryWithType>().ToFactory(); 

我做错了什么,还是不支持这种方式?在我目前的情况下,我不能使用通用版本,因为类型来自运行时参数。我可以用MakeGenericMethod和朋友的反射黑客,但我想避免这种情况。

回答

1

这不支持开箱即用。但是你可以通过做交换IInstanceProvider用自定义实现:

kernel.Bind<IFooFactory>() 
    .ToFactory(() => new MyCustomInstanceProvider()); 

另见wiki以获取更多信息。

此外Ninject factory create T based on enum可能会对你感兴趣。

IInstanceProvider的实现看上去像(我没有测试它是否真的编译,不好意思):

internal class TypeDefinedByArgumentInstanceProvider : StandardInstanceProvider 
{ 
    protected override Type GetType(MethodInfo methodInfo, object[] arguments) 
    { 
     return (Type)arguments.Single(); 
    } 
} 

kernel.Bind<IFooFactory>() 
    .ToFactory(() => new TypeDefinedByArgumentInstanceProvider()); 
+0

谢谢,这看起来很有希望,我很高兴地看到,它没有太多的代码要么:) –

0

我不知道我是否有正确你的问题。 是不是你必须将IFoo绑定到你的具体类型?

 kernel = new StandardKernel(); 
    kernel.Bind(typeof(IFoo)).To<Class2>(); 
    kernel.Bind<IFooFactoryWithType>().ToFactory(); 
    var createdInstance = kernel.Get<IFooFactoryWithType>().Create(typeof(IFoo)); 
+0

在这种情况下,没有,因为有更多的具体类型,我在运行时要求。我想把这个请求委托给Ninject和这样一家工厂。 –