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 依賴項注入其唯一的公共構造函數中。

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");

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
- 3 回答
- 0 關注
- 792 瀏覽
添加回答
舉報