.NET Core Scoped通过DI在Singleton中调用

时间:2018-05-16 04:47:30

标签: c# dependency-injection asp.net-core-2.0

我在2.0中遇到了一个错误,我以前没有进入.Net Core 1.1。

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

我正在使用Hangfire,我需要它来访问我的数据库(所以我通过DI注入我的上下文)以按计划从API更新数据库中的一些数据。所以看起来DbContext被实例化为Scoped,我将我的Hangfire服务设置为Singleton。在Core 1.1中,没有检查嵌套在Singleton中的Scoped。我知道这个概念有效,因为我在Core 1.1项目中将其从我的另一个项目中删除,并将Context嵌套在我的Singleton服务中工作正常。 (令我烦恼的是微软觉得有必要控制我,因为我可能做坏事)。

所以,我将我的Hangfire服务从Singleton更改为Scoped,希望因为我的DbContext显然是Scoped,Scoped里面的Scoped会很好,而是我得到这个错误:Cannot resolve scoped service 'ArithmosDaily.IHangfireJobSchedulerService' from root provider.我仍然不知道那个是什么甚至意味着。

在做了一点挖掘之后,我偶然发现了帖子底部的两个链接(到目前为止,我只能找到它)。我尝试按照第一个链接中的建议在我的启动中设置services.BuildServiceProvider(false);,但这并没有改变我的配置中的任何内容:我在设置服务时仍然收到错误。

我完全难过,不知道还有什么可以尝试的。也许我在错误的地方有代码?我不确定。

以下是我的启动和配置代码:

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>();
}

我遇到过这些问题,但他们没有太多帮助我:

ASP.Net Core 2 ServiceProviderOptions.ValidateScopes Property

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

1 个答案:

答案 0 :(得分:1)

  

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

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

  

我的Singleton服务中的Context工作正常。

这样的事情是相当特殊的,这就是为什么在默认情况下阻止它是一件好事。例如,DbContext不是线程安全的,并且在应用程序持续时间内保持活动状态几乎在所有情况下都会导致并发错误,这些错误只会在生产中运行时出现,同时多个请求同时进入。

这不会导致您的情况出现错误,这是例外情况,而不是规则。

  

无法从根提供程序解析作用域服务“ArithmosDaily.IHangfireJobSchedulerService”。我仍然不知道那个甚至意味着什么。

这个错误确实令人困惑。这意味着,对于.NET Core容器,您应始终从IServiceScope解决,而不是从IServiceProvider解决。在ASP.NET Core请求中运行时,框架将代表您自动调用ServiceProviderServiceExtensions.CreateScope并使用该范围为您解析控制器和其他服务。在Web请求外部运行时,您可能需要自己创建一个范围。