2010-03-07 64 views
6

考慮以下幾點:Ninject 2.0 - 綁定到多次使用相同接口的對象?

public Something(IInterface concreteObjectOne, IInterface concreteObjectTwo) 
    { 
     this.concreteObjectOne = concreteObjectOne; 
     this.concreteObjectTwo = concreteObjectTwo; 
    } 

如何設置設置此類型與Ninject結合起來?我試着用谷歌搜索這個詞,但是因爲我不確定這個名字叫什麼,我也不知道,我也不能在維基上找到任何關於這個的東西。

編輯

我相信這就是所謂的以公約爲基礎的結合,如所描述here。但是,此文檔適用於版本1.0,而2.0不具有Only方法。我希望這可以在沒有屬性的情況下實現 - 使用名稱約定或類似的東西。

回答

9

除了使用「唯一」方法,本文還通過爲注入對象指定不同的屬性來提出另一種解決方案。

例子:

public class ObjectOneAttribute : Attribute 
{ 

} 
public class ObjectTwoAttribute : Attribute 
{ 

} 

然後

public Something([ObjectOneAttribute] IInterface concreteObjectOne, [ObjectTwoAttribute] IInterface concreteObjectTwo) 
    { 
     this.concreteObjectOne = concreteObjectOne; 
     this.concreteObjectTwo = concreteObjectTwo; 
    } 

而當你想界面到正確的具體對象綁定,使用 「WhereTargetHas」 的方法:

Bind<IInterface>().To<YourConcreteTypeOne>().WhereTargetHas<ObjectOneAttribute>(); 
Bind<IInterface>().To<YourConcreteTypeTwo>().WhereTargetHas<ObjectTwoAttribute>(); 

更新:解不使用屬性:
使用方法 「當」:

Bind<IInterface>().To<YourConcreteTypeOne>().When(r => r.Target.Name == "concreteObjectOne"); 
Bind<IInterface>().To<YourConcreteTypeTwo>().When(r => r.Target.Name == "concreteObjectTwo") 

;

+0

我寧可不添加屬性。文章結尾展示瞭如何利用慣例,例如該參數被命名爲X.這就是我真正想要的。 – Finglas 2010-03-07 13:25:57

+0

@Finglas我更新了另一個解決方案 – 2010-03-07 13:31:10

+0

這很棒。當我在玩弄這個工作時,我很接近,但是你很清楚。順便說一下,我沒有任何反對屬性的東西,在這種情況下我發現它很浪費。這種類型的配置在我的代碼庫中並不常見,所以使用When方法更好。乾杯。 – Finglas 2010-03-07 13:37:38

5

如果我可能被允許提供一些通用的,而不是Ninject特定的指導,我建議你稍微重新考慮你的設計。目前的構造函數是含糊,因爲它沒有提供關於IInterface的哪個實現在哪裏的指導 - 我意識到這僅僅是您真實API的模型,而真正的API可能會爲開發人員提供更多幫助恰當命名參數的形式,像DI容器這樣的機器無法推斷正確的用法。

許多DI容器提供了一些方法來解決這種模糊問題,例如通過提供可用於將名稱(元數據)與每個依賴項相關聯的屬性。 AFAIR,Ninject有Inject屬性...

然而,考慮幾個選擇:

第一個選擇是封裝在兩個類似的接口實例在參數對象,像這樣:

public interface IParameterObject 
{ 
    IInterface ObjectOne { get; } 

    IInterface ObjectTwo { get; } 
} 

您現在可以更改構造函數以獲取IParameterObject的實例,而不是使用兩個接口實例本身。

public Something(IParameterObject po) 
{ 
    this.concreteObjectOne = po.ObjectOne; 
    this.concreteObjectTwo = po.ObjectTwo; 
} 

這意味着您可以將IParameterObject的配置推送到Composition Root

另一種方法去思考是,是否是有意義的考慮兩個實例只是一個特殊情況更普遍的設計,採用實例的任何數量的的情況。這可能並非總是如此,但如果是這樣,你可以改變構造這樣:

public Something(IEnumerable<IInterface> objects) 

我個人喜歡的任何的上述建議在使用特定Ninject功能什麼,因爲它迫使我通常使API更明確,從而更易於讀取和維護。

+0

@Mark。您昨天回答(再次感謝)讓我使用工廠,以便爲我的可插入算法使用策略設計模式。有問題的工廠現在採用兩個具體對象,但由於我使用的是戰略模式,它們都是相同的界面。通常沒有IOC,我會編寫這樣的代碼並手動連接依賴關係。它也使得單元測試變得容易。雖然你的建議可以起作用,但我總覺得它是有用的。對於2.0,我似乎無法找到正確的方式做任何事情,只是簡單的綁定。 – Finglas 2010-03-07 13:24:21

+0

夠公平 - 很高興你找到了解決方案:) – 2010-03-07 14:10:21

相關問題