Asp.net

ASP.Net Core 2 ServiceProviderOptions.ValidateScopes 屬性

  • December 24, 2020

ServiceProviderOptions.ValidateScopes到底是什麼?我覺得我無法完全理解它在引擎蓋下的作用。我在教程中遇到過這個問題,但沒有解釋。

我假設您正在談論這段程式碼:

services.BuildServiceProvider(new ServiceProviderOptions
{
   ValidateScopes = true
});
// or 
services.BuildServiceProvider(true); // or false

?

ASP.NET Core Provider 有一個機制,可以驗證作用域服務是否由單例容器解析。ASP.NET Core 有兩種容器。在應用程序的生命週期內有效的主單例容器和每個請求的作用域容器。

此選項將阻止從單例容器解析範圍服務,也就是說,如果您不小心嘗試在Configure方法中解析範圍服務,您將收到異常。而如果你禁用它,你不應該。

public void Configure(IApplicationBuilder app)
{
   // will throw exception, since by default DbContext is registered as scope
   app.ApplicationServices.GetRequiredService<MyDbContext>();
}

例外是類似於

InvalidOperationException:無法從根提供程序解析“IExampleService”,因為它需要範圍服務“MyDbContext”。

這種行為是為了防止記憶體洩漏並從單例容器中解析作用域服務(應該是短命的),本質上也使這些服務也成為准單例(因為在容器被釋放並且單例之前它們不會被釋放)容器僅在應用程序關閉時被釋放)。

在 ie 方法中解析作用域服務的正確Configure方法是這樣

// get scoped factory
var scopedFactory = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>();
// create a scope
using (var scope = scopedFactory.CreateScope())
{
   // then resolve the services and execute it
   var context = scope.ServiceProvider.GetRequiredService<MyDbContext>();
}
// here, the child (scoped) container will be disposed and all scoped and transient services from it

更新 12/2020:預設值現在false是 .NET 5.0

預設值是true 除非你確切地知道你在做什麼,否則你應該保持這樣的狀態,否則你可能會因未發布的服務而冒著嚴重的記憶體洩漏(或對像已經處理的異常)的風險。

引用自:https://stackoverflow.com/questions/50198609