亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何將依賴項注入靜態類

如何將依賴項注入靜態類

C#
滄海一幻覺 2022-01-16 20:00:41
我一直在用 DI 制作簡單的記錄器類,但我有一些問題和疑問。有一個問題。如果我用 DI 創建一個記錄器類。每當我使用它時,我都應該這樣使用它。var logger = new LogService(new FileLogger());logger.WriteLine("message");我想把它變成靜態類,但是沒有辦法在靜態類中通過構造函數注入依賴。所以,我這樣改。public static class LogService(){    private static readonly ILoggable _logger;    static LogService()    {         _logger = new FileLogger();    }}我覺得這太奇怪了。這不是DI..沒有一種向靜態類注入依賴的好方法嗎?
查看完整描述

3 回答

?
牛魔王的故事

TA貢獻1830條經驗 獲得超3個贊

依賴注入作為一種實踐,旨在引入抽象(或接縫)以解耦易變的依賴關系。易失性依賴是一個類或模塊,除其他外,它可以包含不確定的行為,或者通常是您可以替換或攔截的東西。

有關 volatile 依賴項的更詳細討論,請參閱我的書的這本可自由閱讀的介紹的第 1.3.2 節。

因為您FileLogger寫入磁盤,它包含非確定性行為。出于這個原因,您介紹了ILoggable抽象。這允許消費者與實現分離FileLogger

但是,為了能夠成功地將消費者與其可變依賴項解耦,您需要將該依賴項注入消費者。共有三種常見模式可供選擇:

構造函數注入和屬性注入都應用應用程序的啟動路徑(也稱為Composition Root)中,并要求使用者將依賴項存儲在私有字段中以供以后重用。這要求構造函數和屬性是實例成員,即非靜態的。靜態構造函數不能有任何參數,靜態屬性會導致Ambient Context 反模式(參見第 5.3 節)和Temporal Coupling。這阻礙了可測試性和可維護性。

另一方面,方法注入是在組合根之外應用的,它不存儲任何提供的依賴項,而只是使用它。

因此,方法注入是三種模式中唯一可以同時應用于實例方法和靜態方法的模式。

在這種情況下,方法的使用者必須提供依賴。然而,這確實意味著消費者本身必須通過構造函數、屬性或方法注入提供該依賴項。

您在其構造函數LogService中創建的靜態示例是緊密耦合代碼的一個很好的示例。FileLogger這被稱為Control Freak 反模式(第 5.1 節),或者通??梢砸暈?a >DIP 違規。這與 DI正好相反。

為了防止 volatile 依賴項的緊密耦合,最好的方法是制作LogService非靜態并將其 volatile 依賴項注入其唯一的公共構造函數中。


查看完整回答
反對 回復 2022-01-16
?
梵蒂岡之花

TA貢獻1900條經驗 獲得超5個贊

將依賴注入 (DI) 與靜態類一起使用是沒有意義的。而不是 DI,只需向靜態類添加一個初始化方法并傳入依賴項。


public static class LogService

{

    private static ILoggable _logger;


    public static ILoggable Logger

    {

        get

        {

             return _logger;

        }

    }


    public static void InitLogger(ILoggable logger)

    {

         _logger = logger;

    }

}

要使用記錄器,只需確保先調用InitLogger():


LogService.InitLogger(new FileLogger());

LogService.Logger.WriteLine("message");


查看完整回答
反對 回復 2022-01-16
?
至尊寶的傳說

TA貢獻1789條經驗 獲得超10個贊

您可以對需要注入靜態類的任何對象使用延遲初始化。

https://docs.microsoft.com/en-us/dotnet/api/system.lazy-1?view=net-5.0

這將允許您傳遞可以在正在運行的實例和需要使用這些對象的其他類/方法之間共享的靜態對象。一個示例是您希望在整個應用程序中共享的 HttpClient。您可以在靜態類中延遲初始化 HttpClient 并引用靜態類來獲取 HttpClient。

這是使用 CosmosDB 客戶端的另一個示例: https ://docs.microsoft.com/en-us/azure/azure-functions/manage-connections?tabs=csharp#azure-cosmos-db-clients


查看完整回答
反對 回復 2022-01-16
  • 3 回答
  • 0 關注
  • 792 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號