公司的某專案經常切換成其他非 Development 的環境開發,而這個專案啟動時會先連資料庫查詢資料,程式碼大致上如以下所示:
1 |
|
這段程式碼部署到 Production 的環境後從未發生例外,但在本地開發時切換成 Development 的環境後就出現例外了,錯誤訊息如下:
System.InvalidOperationException: 'Cannot resolve scoped service 'TestService' from root provider.'
這時想起在 Singleton 物件注入 Scoped 物件時,這個 Scoped 物件本身就跟 Singleton 物件沒什麼不同,而這個 Scoped 物件在應用程式關閉時才會被釋放,這可能會造成一些問題
但奇怪的是為何在 Production 的環境不會報錯,在 Development 的環境才會報錯呢?
深入原始碼
後來在原始碼中尋找發生這個現象的原因,從 WebApplication.CreateBuilder(args)
這一行程式碼往下找,最後在 HostingHostBuilderExtensions.cs 找到解答
1 |
|
從這段原始碼可以得知只有在 Development 的環境下,ValidateScopes
和 ValidateOnBuild
為 true
,這在開發時期能避免這種隱藏的問題發生
而這兩個屬性會在 ServiceProvider.cs 的建構函式中進行 Scope 的檢查
1 |
|
解決方法
先使用 CreateScope
建立 Scope 後再去取得物件,避免從根容器取得物件
1 |
|