2016-02-16 132 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和這樣一家工廠。 –