簡體   English   中英

依賴注入或服務位置?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM