【问题标题】:ASP.Net Core 2 ServiceProviderOptions.ValidateScopes PropertyASP.Net Core 2 ServiceProviderOptions.ValidateScopes 属性
【发布时间】:2018-05-06 10:22:56
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    我假设你说的是这段代码:

    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~~,除非你确切地知道你在做什么,否则你应该保持这样的状态,否则你可能会因未发布的服务而导致严重的内存泄漏(或对象已经处理的异常)。

    【讨论】:

    • 我遇到了一些麻烦。我有一个类似的问题。我正在使用 Hangfire,我需要它来访问我的数据库,以便按计划使用 API 中的一些数据对其进行更新。我尝试在启动中的服务设置中设置ValidatesScopes = true,但这并没有改变我的配置中的任何内容:设置服务时仍然出现错误。我理解 MS 这样做的原因,但令人讨厌的是,他们强迫我做一些我知道在 1.1 中运行良好的事情:例如,我没有内存问题,等等。
    • 此外,我将其从 Singletion 更改为 Scoped,希望由于我的 DbContext 显然是 Scoped 的,因此 Scoped 内的 Scoped 会很好,相反我收到此错误:'Cannot resolve scoped service'ArithmosDaily.IHangfireJobSchedulerService'来自根提供商。'
    • @RobertBurke: ValidatesScopes = true 是默认值...您可能希望 ValidateScopes = false 禁用此验证
    • @Tseng 抱歉,这是一个复制/粘贴错误。我确实将它设置为 false。
    • 抱歉,我已将此移至我自己的问题。它有点大,上述分辨率对我没有帮助。希望问我自己的问题会给我一个答案。以上更多是一种解释,但不是对我有帮助的实际实现。不过谢谢!
    猜你喜欢
    • 2018-08-19
    • 1970-01-01
    • 2018-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-04
    相关资源
    最近更新 更多