究竟什么是 ServiceProviderOptions.ValidateScopes ?我觉得我无法完全理解它在引擎盖下的作用。我有一个教程,但没有解释。
答案 0 :(得分:7)
我假设您正在谈论这段代码:
services.BuildServiceProvider(new ServiceProviderOptions
{
ValidateScopes = true
});
// or
services.BuildServiceProvider(true); // or false
ASP.NET核心提供程序有一个机制,可以验证单例容器是否解析了作用域服务。 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'。
这种行为是为了防止内存泄漏并解决单例容器中的作用域服务(应该是短命),实质上也使这些服务成为单单元(因为它们不会放置,直到容器被处理,单个容器只在应用程序关闭时被处理掉。)
在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
默认值为true
,您应该保留它,除非您确切知道自己在做什么,否则您可能会因未发布的服务而冒着令人讨厌的内存泄漏(或对象已经处置的异常)的风险。