ASP.Net Core 2 ServiceProviderOptions.ValidateScopes属性

时间:2018-05-06 10:22:56

标签: asp.net asp.net-core asp.net-core-mvc

究竟什么是 ServiceProviderOptions.ValidateScopes ?我觉得我无法完全理解它在引擎盖下的作用。我有一个教程,但没有解释。

1 个答案:

答案 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,您应该保留它,除非您确切知道自己在做什么,否则您可能会因未发布的服务而冒着令人讨厌的内存泄漏(或对象已经处置的异常)的风险。