2017-01-25 53 views
1

我是新來的DI(使用Ninject)和剛開始學的概念,但我一直在抓我的頭一會兒就明白這一點:Ninject - 綁定不同的接口實現同一類

假設我的程序中有相同類的不同用法(下例中爲ProcessContext)。

第一類(SomeClass):我想注入Implement1ProcessContext實例。

第二類(SomeOtherClass):我想將Implement2注入ProcessContext實例。

我該如何使用Ninject來執行綁定?

public class Implement1 : IAmInterace 
{ 
    public void Method() 
    { 
    } 
} 

public class Implement2 : IAmInterace 
{ 
    public void Method() 
    { 
    } 
} 

public class ProcessContext : IProcessContext 
{ 
    IAmInterface iamInterface; 
    public ProcessContext(IAmInterface iamInterface) 
    { 
     this.iamInterface = iamInterface; 
    } 
} 

public class SomeClass : ISomeClass 
{ 
    public void SomeMethod() 
    { 
     // HERE I WANT TO USE: processcontext instance with Implement1 
     IProcessContext pc = kernel.Get<IProcessContext>();    
    } 
} 

public class SomeOtherClass : ISomeOtherClass 
{ 
    public void SomeMethod() 
    { 
     // HERE I WANT TO USE: processcontext instance with Implement2 
     IProcessContext pc = kernel.Get<IProcessContext>();    
    } 
} 
+0

這聽起來像你需要的東西像[策略模式](http://stackoverflow.com/a/32415954/181087),使您可以選擇基於參數的實現。這是另一個[示例](http://stackoverflow.com/a/31971691/181087),它將抽象工廠的相同模式組合在一起,以實時獲取實例。 – NightOwl888

回答

0

您可以使用named bindings

例如是這樣的:

Bind<IProcessContext>() 
    .To<ProcessContext>() 
    .WithConstructorArgument("iamInterface", context => Kernel.Get<Implement1>()) 
    .Named("Imp1"); 

Bind<IProcessContext>() 
    .To<ProcessContext>() 
    .WithConstructorArgument("iamInterface", context => Kernel.Get<Implement2>()) 
    .Named("Imp2"); 

kernel.Get<IProcessContext>("Imp1"); 
+0

謝謝! 你可以進一步解釋如何用SimpleInjector來做到這一點嗎? – ohadinho

+1

@ohadinho對不起,我沒有任何SimpleInjector的經驗。你應該爲那個圖書館開一個新的問題。 –

+0

發現在SimpleInjector中存在基於上下文的注入: http://simpleinjector.readthedocs.io/en/latest/advanced.html#context-based-injection – ohadinho

0

您可以用這種方式很容易注入額外的構造函數參數:

public void SomeMethod() 
{ 
    var foo = new Ninject.Parameters.ConstructorArgument("iamInterface", new Implement2()); 
    IProcessContext pc = kernel.Get<IProcessContext>(foo);    
} 

現在,我不必ninject訪問。所以告訴我它是否按預期工作。

+0

在我的例子中,我只使用了2個接口。發生什麼「富」有相同的問題?如果Implement2在構造函數中獲取IAmInterface2,我將再次需要設置ConstructorArgument。 有沒有更簡單的方法? – ohadinho

+0

@ohadinho在你的情況下,你想傳遞一個具體類型到'IProcessContext'。其實你不想使用DI容器。但是如果'Implement2'需要一些其他接口,因爲它是參數,你必須注入所需的參數。我的意思是通常你從'Ninject'本身得到你的實例,讓'Ninject'將參數傳遞給它。 – Feriloo

0

這是不可能的,因爲Ninject無法知道要返回哪個實現。然而;如果您通過傳入變量來創建IProcessContext的新實例,那麼Ninject將使用適當的構造函數查找實現並返回該實例。

相關問題