2012-06-11 125 views
4

我一直在使用Ninject短的時間不同的實現,我試圖找出如何做一些事情,我在Unity已經做了的app.config/web.config中的條目。Ninject綁定

我敢肯定,這是簡單的,只是還沒有找到實現它的最好方式,當然Ninject沒有周圍最大的文檔。

我想有不同的實現一個接口,在代碼中沒有改變 - 具體應用知道使用哪種實現。

例如,當我用統一,我將有一個活的應用程序和一個單元測試庫中,使用不同的數據庫。所以:

var repo = IoC.Get<IRepository>(); 

會回到我住的應用程序一個RealRepositoryFakeRepository在我的單元測試。我只是簡單地將這些類映射到我的app.config或web.config中。

在Ninject中,由於您在代碼中定義了映射,似乎沒有辦法決定使用哪個實現(或哪個模塊),除了代碼中 - 但當然,整個目的是我不想特別說明我想要使用哪個實現。

有沒有很好的方法來做到這一點?我能想到的唯一方法就是從配置文件中動態選擇NinjectModule實現,但這樣做感覺不對。

回答

8

是聽起來像你missusing IoC容器作爲服務定位器。這給你很多問題。其中之一是測試更困難。我建議做的對,而不是服務地點做建設者強制措施。

這意味着不是

public class MyClass 
{ 
    public void Do() 
    { 
     var repo = IoC.Get<IRepository>(); 
     .... 
    } 
} 

你做

public class MyClass 
{ 
    private IRepository repo; 
    public MyClass(IRepository repo) 
    { 
     this.repo = repo; 
    } 

    public void Do() 
    { 
     .... 
    } 
} 

現在只是一個獲取應用程序的根目錄。其他一切都通過構造函數傳遞。

它使測試很簡單:

var testee = new MyClass(new Mock<IRepository>()); 
+0

直接從馬的嘴巴。 :) 好答案;我忽略了詳細說明'IoC.Get ()'暗示的誤用。 –

+0

你是對的 - 當我在配置文件中使用Unity時,它可以讓我完全避免依賴注入,只是將它用作定位器。你讓我在自己腦海中做了180分鐘,以考慮正確使用DI。謝謝。 –

2

您的實時應用程序和您的單元測試庫是否有不同的端點?一個大概是一個單元測試項目(nunit?),另一個是應用程序(控制檯,窗口或asp.net)。

每種類型的應用程序的應獨立地定義它們的綁定,通常通過定義單獨的模塊(即傳遞給的StandardKernel構造)。一組爲您的真實應用提供映射,另一組爲您的單元測試提供映射。後者可能是也可能不是必需的 - 理想情況下,您正在測試的特定類的依賴關係應該很容易被嘲弄和傳遞,根本不需要使用Ninject。在實踐中,我發現很多借口仍然使用Ninject,在這種情況下,我創建了一個單獨的模塊,或者只是在測試本身中重新綁定內核。

+0

在我使用Ninject的最新版本,慣用的方式是創建單獨的項目單獨的模塊。但是,在單元測試中,由於需要進行混合和匹配,您可能會有更多。 –

+0

當你直接調用某些東西時,或者我有每個實現的測試版本時,這應該很好。但假設我有一個商業課,我不嘲笑,它使用Ninject調用數據存儲庫。在我的測試中,我將調用業務類的生產實現,但我希望它調用我的測試數據存儲庫。由於業務類不知道它在哪個環境中,它不知道稱爲測試回購。 –

+0

我應該澄清我的評論。我假設業務類創建一個新的內核,並且該內核不會有測試映射。如果這個假設是錯誤的,那麼這可能是我的問題。 –