在我的作業中,我們正在開發 ASP.NET 核心應用程式。我一直看到使用依賴注入的以下模式。在此示例Logic中取決于OtherLogic:
public class Logic {
private readonly OtherLogic myOtherLogic;
public Logic(OtherLogic myOtherLogic) {
// I mean specifically this pattern of checking injected dependencies for null:
this.myOtherLogic = myOtherLogic
?? throw new ArgumentNullException(nameof(myOtherLogic));
}
}
所有依賴項都添加到IServiceCollection服務配置期間,并且 (Logic和OtherLogic) 都只能從依賴項注入中檢索。在我當前的專案中,我使用的是 DotNet 5,如果這很重要,我已經啟用了可為空的參考型別。
我想放棄這個 Guard Clause 模式,因為我相信注入器在無法決議非可選服務時總是會拋出例外(在服務配置期間)。我的問題是,在什么情況下注入器可以為非可選服務注入空參考?甚至可能嗎?
這篇文章沒有提到null被注入的可能性,但據我所知,也沒有明確否認。只是想確保我以后不會遇到麻煩,謝謝你的時間:)
uj5u.com熱心網友回復:
在“正常”條件下(即僅取決于使用自動接線時)null無法注入值。但是,以下代碼片段顯示了何時null可以將參考注入的示例Logic:
案例一:人工施工
new Logic(null);
通過使用普通 C# 手動呼叫其建構式,始終可以在 DI 容器的背景關系之外創建實體。在大多數情況下,您不會null直接注入,但發生這種情況的原因可能有很多,例如通過呼叫方法來檢索依賴項,而此方法具有回傳 null 的默認情況,或者當依賴項來自尚未初始化的靜態欄位,如果靜態欄位相互依賴,則可能發生這種情況。
案例2:通過工廠注冊直接空注入
services.AddTransient(c => new Logic(null));
這個案例實際上與案例 1 相同,但現在您將創建包裝在注冊的工廠委托中。
案例三:工廠中不正確使用GetService反對GetRequiredService
services.AddTransient(c => new Logic(c.GetService<OtherLogic>()));
MS.DI 容器包含一個GetService<T>允許檢索依賴項的方法,但null在注冊T不存在的情況下回傳。因此,錯誤配置可能會null被注入。相反,您應該幾乎總是呼叫GetRequiredService<T>擴展方法,它確保例外被拋出并且null永遠不會回傳。甚至在注冊依賴項時GetRequiredService<T>拋出例外,但其工廠委托回傳,如下一個案例所示。null
null案例 4:具有從工廠注冊回傳的依賴項的自動注冊
services.AddTransient<Logic>();
services.AddTransient<OtherLogic>(c => null);
在這種情況下,進行工廠注冊,直接或(更常見)間接null參考。MS.DI 允許將該null參考OtherLogic注入Logic.
在我看來,選項 4 不應該被允許,我認為它是 MS.DI 中允許工廠注冊回傳的設計流程null。Logic但這仍然留下了使用普通 C# 呼叫建構式的其他三種情況。
您是否想非常安全并使用保護條款保護班級的先決條件取決于您。就個人而言,對于我使用不允許案例 4 并且難以執行案例 3 的 DI 容器的應用程式,我通常會省略保護子句。這甚至允許我使用更簡潔的record語法:
// WARNING: No null checks are performed in the record constructor
public sealed record Logic(OtherLogic MyOtherLogic)
{
}
作為一個反駁論點,值得一提的是,添加這些空檢查保護子句不會導致任何可維護性問題,因為它們在撰寫后不會改變。它們是班級的 DI 基礎設施的一部分,雖然有點吵,但從長遠來看不會引起徹底的變化。
uj5u.com熱心網友回復:
沒有必要使用依賴注入檢查傳遞給建構式的引數,因為(如您所提到的)在注冊依賴項時會發生例外,如您所提到的。
我在這里找到了一篇關于這個主題的文章,有人建議未來的 DI 實作可能會導致空注入:https ://stevetalkscode.co.uk/null-injection
然而,這篇文章是假設性的,場景非常具體。我認為擺脫空檢查是可以的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/494970.html
