2011-11-25 79 views
2

我剛剛在我的ASP.NET MVC 3應用程序中開始使用Ninject(v2.2.0.0)。到目前爲止,我對此感到非常激動,但是我遇到了我似乎無法解決的情況。使用Ninject將接口綁定到編譯時未知的多個實現

我想要做的是將接口綁定到具體的實現,並讓Ninject能夠使用工廠(也將註冊Ninject)將具體實現注入到構造函數中。問題是,我想我的構造函數引用具體類型,而不是接口。

下面是一個例子:

public class SomeInterfaceFactory<T> where T: ISomeInterface, new() 
{ 
    public T CreateInstance() 
    { 
     // Activation and initialization logic here 
    } 
} 

public interface ISomeInterface 
{ 
} 

public class SomeImplementationA : ISomeInterface 
{ 
    public string PropertyA { get; set; } 
} 

public class SomeImplementationB : ISomeInterface 
{ 
    public string PropertyB { get; set; } 
} 


public class Foo 
{ 
    public Foo(SomeImplementationA implA) 
    { 
     Console.WriteLine(implA.PropertyA); 
    } 
} 

public class Bar 
{ 
    public Bar(SomeImplementationB implB) 
    { 
     Console.WriteLine(implB.PropertyB); 
    } 
} 

在其他地方,我想只使用接口綁定:

kernel.Bind<Foo>().ToSelf(); 
kernel.Bind<Bar>().ToSelf(); 
kernel.Bind(typeof(SomeInterfaceFactory<>)).ToSelf(); 
kernel.Bind<ISomeInterface>().To ...something that will create and use the factory 

然後,請求從Ninject的Foo實例時,它會看到其中一個構造函數參數實現了一個綁定接口,獲取工廠,並實例化正確的具體類型(SomeImplementationA)並將其傳遞給Foo的構造函數。

這背後的原因是我會有許多ISomeInterface的實現,我寧願避免單獨綁定每一個。這些實現中的一些可能在編譯時並不知道。

我試着使用:

kernel.Bind<ISomeInterface>().ToProvider<SomeProvider>(); 

提供商檢索根據當時所請求的服務類型調用它的CreateInstance方法,返回的具體類型的工廠:

public class SomeProvider : Provider<ISomeInterface> 
{ 
    protected override ISomeInterface CreateInstance(IContext context) 
    { 
     var factory = context.Kernel.Get(typeof(SomeInterfaceFactory<>) 
      .MakeGenericType(context.Request.Service)); 
     var method = factory.GetType().GetMethod("CreateInstance"); 
     return (ISomeInterface)method.Invoke(); 
    } 
} 

然而,我的供應商從來沒有調用。

我很好奇Ninject是否可以支持這種情況,如果是的話,我可能會如何解決這個問題。

我希望這是足夠的信息來解釋我的情況。請讓我知道我是否應該進一步闡述。

謝謝!

回答

1

看來你錯誤地理解了ninject是如何工作的。如果你創建Foo,它會看到它需要一個SomeImplementationA並且會嘗試爲它創建一個實例。因此,您需要爲SomeImplementationA定義綁定,而不是ISomeInterface

由於您依賴具體實例而不是抽象,因此您的實現也很有可能違反了依賴性倒置原則。

一次註冊所有類似類型的解決方案(以及配置IoC容器的首選方式)是按照約定使用配置。請參閱Ninject.Extensions.Conventions擴展。

相關問題