2013-02-06 114 views
2

我想學習依賴注入,並且還有很多細節我還沒有把握。我爲此開始閱讀的一本書是Karl Seguin的Foundations of Programming。有一個關於依賴注入的例子:依賴注入或服務位置?

public class Car 
{ 
    private int _id; 

    public void Save() 
    { 
     if (!IsValid()) 
     { 
      //todo: come up with a better exception 
      throw new InvalidOperationException("The car must be in a valid state"); 
     } 

     IDataAccess dataAccess = ObjectFactory.GetInstance<IDataAccess>(); 
     if (_id == 0) 
     { 
      _id = dataAccess.Save(this); 
     } 
     else 
     { 
      dataAccess.Update(this); 
     } 
    } 
} 

然後他繼續並建議增加間接的另一個層面,而不是直接在方法調用ObjectFactory

public static class DataFactory 
{ 
    public static IDataAccess CreateInstance 
    { 
     get 
     { 
      return ObjectFactory.GetInstance<IDataAccess>(); 
     } 
    } 
} 

但不是這個「服務地點「其實?

回答

2

它是服務定位器。有幾種方法可以使用依賴:

  • 聚合(例如殼體)

  • 組合物

    • DI在構造函數中,強制性的(可以使用在上電平SL被注入)

    • DI屬性,可選(可以在上層使用SL注入)

選擇什麼取決於許多因素,例如是否是穩定或不穩定的依賴,你是否需要模擬它在測試與否等,有好書DI在所謂的「依賴注入。 NET'by Mark Seemann。

+0

我有Seemann的書,但它太詳細了,一開始太理論化了(至少這是我的感受)。儘管稍後我在學習了更多關於該主題後引用了本書的部分內容,並且對本書有所幫助。你有沒有其他書籍和/或在線資源建議? – hattenn

+0

您可以嘗試通過Bob叔叔的「敏捷軟件開發,原則,模式和實踐」。有幾個關於DI的章節。 (無論如何,我推薦閱讀整本書。) – andreycha

+0

我也可以推薦Mark Seemann的DI書:) – Ian

1

是的,看起來像SL給我。依賴注入傳統上遵循兩種模式之一:財產注入或構造注入。

依賴注入首先感覺比服務位置更努力,但服務位置(SL)有一些否定。服務定位器很容易就會瘋狂地請求服務,隨時隨地。這很好,直到你重構並意識到耦合「太高了」。

隨着DI我更喜歡構造函數注入形式,因爲它迫使我想到誰需要什麼。這就是說,我當前的項目是作爲一個使用服務定位器的綠色領域項目開始的,因爲它給了我靈活的「不」來考慮依賴性並讓應用程序的形態發展。後來,我一直在重構使用DI,主要是爲了處理依賴於什麼和爲什麼的東西。

+1

http://cdn.memegenerator.net/instances/400x/34457009.jpg –

1

你的例子是ServiceLocator。總是有一個ServiceLocator。我想說的關鍵是要理解你爲什麼直接使用它,爲什麼你可能不需要。

關鍵概念是依賴倒置原理。控制框架的依賴注入和反轉是促進委託人應用的工具。理想情況下,您希望您的對象構造函數參數成爲接口定義,這將在對象創建時解析。

如果您使用的是現代工具,例如asp。net MVC,那麼你可以訪問所謂的組合根,這是應用程序的入口點。在MVC中,它是控制器。由於您可以訪問組合根,所以您不需要使用ServiceLocator,因爲您需要註冊和設置IOC框架來從頂層爲注入驅動注入。基本上你的控制器有一些構造函數參數,如ISomeService,它在IOC中註冊並在控制器實例創建時自動注入。如果ISomeService具有一些依賴關係,那麼它們也將作爲ISomeUtility存在於構造器中,等等,隨着對象越來越深入。這非常理想,您永遠不需要使用ServiceLocator來解析對象。

如果您處於使用不允許您訪問根的技術的情況,或者如果您想要在沒有應用程序的應用程序中開始使用IOC框架,並且您正在爲第一個應用程序添加它那麼你可能會發現你無法到達組合根。這可能是框架或代碼質量的限制。在這些情況下,您必須使用ServiceLocator或直接自己創建對象。在這些情況下使用ServiceLocator是可以的,並且比自己創建該對象更好。

+0

這個例子來自書本身,而不是來自我。 – hattenn