.NET Core Scoped通过DI在Singleton中调用 [英] .NET Core Scoped called in Singleton through DI

查看:25
本文介绍了.NET Core Scoped通过DI在Singleton中调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在2.0版本中遇到了一个错误,以前我没有在.Net Core 1.1中获得该错误.

无法使用单例"ArithmosDaily.IHangfireJobSchedulerService"中的作用域服务"ArithmosDaily.Data.ArithmosContext".

我正在使用Hangfire,我需要它来访问数据库(因此我通过DI注入了上下文)以按计划使用API​​中的某些数据更新数据库.因此,似乎DbContext被实例化为Scoped,并且我将我的Hangfire服务设置为Singleton.在Core 1.1中,不检查嵌套在Singleton内的Scoped.我知道这个概念有效,因为我将其从Core 1.1项目的另一个项目中剔除了,并将Context嵌套在我的Singleton服务中可以正常工作.(这让我很生气,微软觉得有必要控制我仅仅是因为我可能做得不好).

因此,我将Hangfire服务从Singleton更改为Scoped,希望由于DbContext显然是Scoped,Scoped内的Scoped会很好,而是出现此错误:无法从以下位置解析范围服务'ArithmosDaily.IHangfireJobSchedulerService'根提供商.我仍然不知道那是什么意思.

进行一些挖掘之后,我发现了帖子底部的两个链接(到目前为止,我所能找到的全部).我尝试按照第一个链接中的建议在Startup中设置 services.BuildServiceProvider(false); ,但这并没有改变我的Configure中的任何内容:设置服务时仍然出现错误./p>

我完全感到困惑,不知道还能尝试什么.也许我在错误的位置输入了代码?我不确定.

这是我用于启动和配置的代码:

  public void ConfigureServices(IServiceCollection服务){services.BuildServiceProvider(false);字符串conn = Configuration.GetConnectionString("Arithmos");services.AddDbContext< ArithmosContext>(options => options.UseSqlite(conn));services.AddMvc();services.AddHangfire(x => x.UseSQLiteStorage(conn));services.AddScoped< IHangfireJobSchedulerService,HangfireJobSchedulerService>();}公共无效的Configure(IApplicationBuilder应用程序,IHostingEnvironment env,IApplicationLifetime生存期){lifetime.ApplicationStarted.Register(OnStartup);life.ApplicationStopping.Register(OnShutdown);如果(env.IsDevelopment()){app.UseDeveloperExceptionPage();app.UseBrowserLink();}别的app.UseExceptionHandler("/Error");app.UseStaticFiles();app.UseMvc(routes =>{route.MapRoute(名称:默认",模板:"{controller}/{action = Index}/{id?}");});app.UseHangfireServer();app.UseHangfireDashboard(options:new DashboardOptions{授权= new [] {new HangfireAuthorizationFilter()}});jobSchedulerService = app.ApplicationServices.GetRequiredService< IHangfireJobSchedulerService>();} 

我遇到了这些问题,但是它们并没有给我带来太大帮助:

ASP.Net Core 2 ServiceProviderOptions.ValidateScopes属性

无法解析范围内的服务Microsoft.AspNetCore.Mvc根提供商提供的.ViewFeatures.Internal.IViewBufferScope

解决方案

在Core 1.1中,没有检查嵌套在Singleton中的Scoped.

实际上是.但是默认情况下未启用它.这是IMO在.NET Core 1中的错误.

我的Singleton服务内部的上下文工作正常.

这种方法非常有用,这就是为什么默认情况下阻止它是一件好事.例如,DbContext不是线程安全的,并且在应用程序运行期间将其保持活动状态几乎会导致并发错误,这些并发错误仅在生产环境中运行时同时出现多个请求时才会出现.

这不会导致您遇到的问题,这是例外,而不是常规.

无法从根提供者解析作用域服务'ArithmosDaily.IHangfireJobSchedulerService'.我仍然不知道那甚至意味着什么.

该错误确实非常令人困惑.这意味着,对于.NET Core容器,您应该始终从 IServiceScope.ServiceProvider (或注入的 IServiceProvider)进行解析,而不是从根源 IServiceProvider <代码>.在ASP.NET Core请求中运行时,框架将代表您自动调用 ServiceProviderServiceExtensions.CreateScope`,并使用该范围为您解析控制器和其他服务.在网络请求之外运行时,您可能需要自己创建一个范围.

I'm getting an error in 2.0 that I used not to get in .Net Core 1.1.

Cannot consume scoped service 'ArithmosDaily.Data.ArithmosContext' from singleton 'ArithmosDaily.IHangfireJobSchedulerService'.

I am using Hangfire, and I need it to access my database (so I inject my context through DI) to update the database with some data from an API on a schedule. So it appears the DbContext is instantiated as Scoped, and I am setting my Hangfire service as a Singleton. In Core 1.1, there was no check for Scoped nested inside a Singleton. I know this concept works, because I ripped it out of another of my projects in a Core 1.1 project and nesting the Context inside my Singleton service works fine. (Which is annoying me that Microsoft feels the need to control me just because I may do something bad).

So, I change my Hangfire Service from Singleton to Scoped, hoping since my DbContext is apparently Scoped, that Scoped inside Scoped would be fine and instead I get this error: Cannot resolve scoped service 'ArithmosDaily.IHangfireJobSchedulerService' from root provider. I still have no clue what that one even means.

After doing a little bit of digging, I came across the two links at the bottom of my post (and so far that's all I can find). I tried setting services.BuildServiceProvider(false); in my Startup as suggested in the first link, but that didn't change anything in my Configure: I still get the error when setting up my service.

I am totally stumped and not sure what else to try. Maybe I have code in the wrong spot? I'm not sure.

Here is my code for Startup and Configure:

public void ConfigureServices(IServiceCollection services)
{
    services.BuildServiceProvider(false);

    string conn = Configuration.GetConnectionString("Arithmos");
    services.AddDbContext<ArithmosContext>(options => options.UseSqlite(conn));

    services.AddMvc();

    services.AddHangfire(x => x.UseSQLiteStorage(conn));
    services.AddScoped<IHangfireJobSchedulerService, HangfireJobSchedulerService>();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime)
{
    lifetime.ApplicationStarted.Register(OnStartup);
    lifetime.ApplicationStopping.Register(OnShutdown);

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseBrowserLink();
    }
    else
        app.UseExceptionHandler("/Error");

    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller}/{action=Index}/{id?}");
    });

    app.UseHangfireServer();
    app.UseHangfireDashboard(options: new DashboardOptions
    {
        Authorization = new[] { new HangfireAuthorizationFilter() }
    });
    jobSchedulerService = app.ApplicationServices.GetRequiredService<IHangfireJobSchedulerService>();
}

I have come across these questions but they haven't helped me too much:

ASP.Net Core 2 ServiceProviderOptions.ValidateScopes Property

Cannot resolve scoped service Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.IViewBufferScope from root provider

解决方案

In Core 1.1, there was no check for Scoped nested inside a Singleton.

There was, actually. But it was not enabled by default. This was IMO a mistake in .NET Core 1.

the Context inside my Singleton service works fine.

That such thing works is rather exceptional, and that's why blocking this by default is a good thing. A DbContext, for instance, is not thread-safe and keeping it alive for the duration of the application will in almost all cases lead to concurrency bugs that will only appear when running in production, when multiple requests come in simultaneously.

It this doesn't cause bugs in your situation, it is the exception, not the rule.

Cannot resolve scoped service 'ArithmosDaily.IHangfireJobSchedulerService' from root provider. I still have no clue what that one even means.

That error is indeed very confusing. What this means is that, with the .NET Core container, you should always resolve from an IServiceScope.ServiceProvider (or an injected IServiceProvider), but never from the rootIServiceProvider. When running inside an ASP.NET Core request, the framework will automatically callServiceProviderServiceExtensions.CreateScope` on your behalf and use that scope to resolve controllers and other services for you. When running outside a web request, you might need to create a scope yourself.

这篇关于.NET Core Scoped通过DI在Singleton中调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆