2010-01-13 52 views
58

我是一個完整的新手到ninjectNinject模塊的用意是什麼?

我已經拉開別人的代碼,發現nInject模塊幾個實例 - 從Ninject.Modules.Module派生的類,並且有一個包含大部分的負載方法他們的代碼。

通過調用StandardKernel實例的LoadModule方法並將它傳遞給模塊類的一個實例來調用這些類。

也許我在這裏丟失了一些明顯的東西,但是這只是創建一個普通的老類並調用它的方法,或者靜態方法與靜態方法有什麼好處呢?

 

回答

61

的Ninject模塊是用來與IoC容器註冊各種類型的工具。優點是這些模塊被保存在自己的類中。這允許你在他們自己的模塊中放置不同的層次/服務。

// some method early in your app's life cycle 
public Kernel BuildKernel() 
{ 
    var modules = new INinjectModule[] 
    { 
     new LinqToSqlDataContextModule(), // just my L2S binding 
     new WebModule(), 
     new EventRegistrationModule() 
    }; 
    return new StandardKernel(modules); 
} 

// in LinqToSqlDataContextModule.cs 
public class LinqToSqlDataContextModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<IRepository>().To<LinqToSqlRepository>(); 
    } 
} 

擁有多個模塊即使在您的IoC容器內也可以分離問題。

其他人的問題聽起來好像更多的是關於IoC和DI整體,而不僅僅是Ninject。是的,您可以使用靜態配置對象來完成IoC容器所做的一切。當有多個依賴關係層次時,IoC容器變得非常好。

public interface IInterfaceA {} 
public interface IInterfaceB {} 
public interface IInterfaceC {} 

public class ClassA : IInterfaceA {} 

public class ClassB : IInterfaceB 
{ 
    public ClassB(IInterfaceA a){} 
} 

public class ClassC : IInterfaceC 
{ 
    public ClassC(IInterfaceB b){} 
} 

建築類C在這一點上是一種痛苦,具有多種深度的界面。僅僅向內核請求IInterfaceC就容易多了。

var newc = ApplicationScope.Kernel.Get<IInterfaceC>(); 
+1

LinqToSqlDataContextModule應該擴展StandardModule? –

+1

@Mark Gibaud不在Ninject 2中。StandardModule已經不存在並替換爲NinjectMdule - http://github.com/enkari/ninject/tree/master/src/Ninject/Modules/ –

+1

這是一個很好的例子,但可測試性呢?我經常聽到DI/IoC容器如何幫助我進行可測試性測試,但是我很難找到一個真實的例子來展示Ninject不會污染我的代碼並且還有助於可測試性。 有沒有現實世界的開源項目,我可以看看想法? –

9

也許我失去了一些東西明顯 這裏,但在剛剛創建一個普通的老班 和調用它的方法,或者一個靜態 類與靜態方法,這是什麼 的好處?

是的,您可以調用一堆Bind<X>().To<Z>()語句來設置綁定,而無需使用模塊。

不同的是,如果你把這些語句的模塊中,然後:

  • IKernel.Load(IEnumerable<Assembly>)可以動態地通過反思發現這樣的模塊,並加載它們。
  • 綁定在邏輯上按名稱組合在一起;你可以使用這個名稱與IKernel.Unload(string)
3

也許我缺少明顯的東西在這裏再次卸載它們,但什麼是該上只創建一個普通的老類和調用它的方法,或者是一個利益靜態類與靜態方法?

對我們來說,這是能夠在以後很容易添加測試。只需重寫一些與mockobjects的綁定即可在沒有連接「一切」的DI的遺留代碼上,幾乎不可能在沒有一些返工的情況下插入測試用例。只要在DI接線一切正常的情況下正確使用DI,即使在可能非常醜陋的遺留代碼上執行該操作也非常簡單。

在許多DI框架中,您可以使用生產模塊進行測試,並使用覆蓋與mockobjects的特定綁定的測試模塊(將其餘配線留在原位)。這些可能是系統測試而不是單元測試,但是我傾向於比普通開發人員更喜歡更高級別的測試,因爲它測試類之間的集成,並且對於加入項目的人來說是很好的文檔,並且可以看到整個功能的實際應用只是功能的一部分)而無需設置整個系統)。