[英]Dependency injection or service location?
我正在嘗試學習依賴注入,並且還有很多微妙之處我尚待掌握。 我為此而開始閱讀的一本書是Karl Seguin的“ 編程基礎 ” 。 有一個關於依賴注入的示例:
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>();
}
}
}
但是,實際上這不是“服務位置”嗎?
它是服務定位器。 有幾種使用依賴項的方法:
匯總(示例案例)
組成
構造函數中的DI,強制性的(可以使用上層的SL注入)
屬性中的DI,可選(可以使用較高級別的SL注入)
選擇什么取決於許多因素,例如,穩定或不穩定的依賴關系,是否需要在測試中模擬它等等。MarkSeemann撰寫了一本關於DI的好書,名為《 .NET中的依賴關系注入》。
是的,在我看來像SL。 傳統上,依賴注入遵循以下兩種模式之一: 屬性注入或構造函數注入。
首先,依賴注入比服務位置更費力,但是服務位置(SL)具有許多負面影響。 使用服務定位器實在太容易了,以至於到處瘋狂地請求服務。 這很好,直到您進行重構並意識到耦合“太該死的太高”為止。
使用DI時,我更喜歡構造函數注入形式,因為它迫使我預先考慮誰需要什么。
綜上所述,我當前的項目是使用服務定位器作為一個綠色項目啟動的,因為它給了我“不”考慮依賴關系並讓應用程序發展的靈活性。 最近,我一直在重構使用DI,主要是為了了解什么依賴於什么以及為什么依賴。
您的示例是ServiceLocator。 總有一個ServiceLocator。 我要說的關鍵是要了解為什么您將直接使用它,以及為什么理想情況下不必使用它。
關鍵概念是依賴性反轉主體。 依賴注入和控制框架的反轉是促進主體應用的工具。 理想情況下,您希望對象的構造函數參數為接口定義,這些定義將在對象創建時解析。
如果您使用的是諸如asp.net MVC之類的現代工具,那么您就可以訪問所謂的合成根,它是應用程序的入口點。 在MVC中,它是控制器。 由於您可以訪問合成根目錄,因此無需使用ServiceLocator,因為注入是由您已經注冊和設置的IOC框架從頂部驅動的。 基本上,控制器具有構造函數參數,例如ISomeService,該參數已在IOC中注冊,並在創建控制器實例時自動注入。 如果ISomeService具有某些依賴關系,則它們也將以ISomeUtility的形式出現在構造函數中,依此類推,隨着對象越來越深。 這是理想的選擇,您將不需要使用ServiceLocator來解析對象。
如果您遇到的情況是使用的技術無法授予您對根的訪問權限,或者您想開始在沒有該應用程序的應用程序中使用IOC框架,而您是第一次添加它,則可以發現您無法到達合成詞根。 這可能是框架或代碼質量的限制。 在這些情況下,您必須使用ServiceLocator或直接自己創建對象。 在這些情況下,使用ServiceLocator是可以的,並且比自己創建該對象更好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.