2010-05-31 42 views

回答

5

我認爲你可能會誤解由Daren Dimitrov提供的答案。除非我誤解了,否則引發此問題的一行是:「另外,您不應該在應用程序的業務層中創建與DI框架的依賴關係

我相信他所說的是應該在應用程序的最高級別創建所有依賴信息/映射。這並不是說你的應用程序的所有層都不會出現依賴性,只是下層不負責設置映射。

如果我的解釋是正確的,那麼我同意他 - 在你的應用程序表面建立你的依賴關係映射。如果他反而說你永遠不應該解決下層的依賴問題,那我就不會同意了。

3

DI應該用於任何情況下,一個組件依賴於另一個組件,無論是UI - > Business,Business - > Data Access或其他。我認爲它不應該只用於UI,它只是讓用戶界面更容易測試,所以似乎有更多的直接好處。

2

我不同意這種說法。您提到的上一個問題不正確,或者您誤解了它。

DI當然不僅僅在UI層中。我只會同意這一點,即控制器是視圖層的一部分。

在任何可以正確提供依賴性的地方使用DI。

無論您選擇使用工廠還是DI解決方案都是您的選擇。

4

應該使用依賴注入(DI)無處不在。但是,請注意,DI只是一組模式 - 不是框架或庫。考慮DI的最佳方式是鬆耦合代碼啓用構造函數注入。你可以寫DI-friendly code all the way without ever referencing a DI Container或使用Service Locator anti-pattern

然後,想到的下一個問題是哪裏應該組成?這可能是原始聲明的意思:only compose the application in the outermost layer - UI或(網絡)服務接口。這就是我所說的組合根。它使代碼的其餘部分保持模塊化和靈活性。

在組合根處,您可以使用Poor Man的DI或適當的DI容器。我強烈建議您使用DI容器,但這不是必需的。

爲了說明我的意思是DI,這裏有一個例子:

public class Foo : IFoo 
{ 
    private readonly IBar bar; 

    public Foo(IBar bar) 
    { 
     if (bar == null) 
     { 
      throw new ArgumentNullException("bar"); 
     } 

     this.bar = bar; 
    } 

    public IBaz Baz(ISnafu snafu) 
    { 
     return this.bar.Snafize(snafu).ToBaz(); 
    } 
} 

的IBaz實現可以從一個定義的Foo類完全獨立的庫實現。此外,消費者在堆棧較高不必知道Foo和伊巴爾任何東西 - 他們可以消耗的IFoo:

public class MyClass : ISomeInterface 
{ 
    private readonly IFoo foo; 

    public MyClass(IFoo foo) 
    { 
     if (foo == null) 
     { 
      throw new ArgumentNullException("foo"); 
     } 

     this.foo = foo; 
    } 

    // ... 
} 

這提供了鬆散耦合是對DI的動機。根據需要重複。

+0

「僅構成最外層的應用程序」應用程序可能會產生誤導。如果您有一個依賴於Web服務的Web應用程序,則Web服務也可以被視爲一個應用程序。所以也許「只在應用程序的邊界上組合對象圖」聽起來更清楚。就我所瞭解的情況而言,您可能在整個應用程序中有多個組合根。 – Rookian 2013-12-03 20:12:44

+2

Web服務是一個單獨的應用程序(單獨的過程)。它甚至可以用不同的語言寫在不同的平臺上。因此,不言而喻,每個應用程序都有一個組合根。 – 2013-12-03 20:32:39