【发布时间】:2018-05-06 10:22:56
【问题描述】:
ServiceProviderOptions.ValidateScopes 究竟是什么?我觉得我无法完全理解它在引擎盖下的作用。我在教程中遇到过这个问题,但没有解释。
【问题讨论】:
标签: asp.net asp.net-core asp.net-core-mvc
ServiceProviderOptions.ValidateScopes 究竟是什么?我觉得我无法完全理解它在引擎盖下的作用。我在教程中遇到过这个问题,但没有解释。
【问题讨论】:
标签: asp.net asp.net-core asp.net-core-mvc
我假设你说的是这段代码:
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”。
这种行为是为了防止内存泄漏并从单例容器中解析范围服务(应该是短暂的),本质上使该服务也成为准单例(因为它们不会直到容器被释放并且单例容器仅在应用程序关闭时才被释放)。
在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
2020 年 12 月更新:The default value is now false for .NET 5.0。
~~默认值是true~~,除非你确切地知道你在做什么,否则你应该保持这样的状态,否则你可能会因未发布的服务而导致严重的内存泄漏(或对象已经处理的异常)。
【讨论】:
ValidatesScopes = true,但这并没有改变我的配置中的任何内容:设置服务时仍然出现错误。我理解 MS 这样做的原因,但令人讨厌的是,他们强迫我做一些我知道在 1.1 中运行良好的事情:例如,我没有内存问题,等等。
ValidatesScopes = true 是默认值...您可能希望 ValidateScopes = false 禁用此验证