c# - 我应该如何将一个DbContext实例注入IHostedService?



asp.net .net (1)

我应该如何(使用标准依赖注入)将 DbContext 实例注入 IHostedService

我试过了什么

我目前让我的 IHostedService 类在构造函数中获取 MainContext (从 DbContext )实例。

当我运行应用程序时,我得到:

无法从singleton'Microsoft.Extensions.Hosting.IHostedService'中使用作用域服务“Microsoft.EntityFrameworkCore.DbContextOptions”。

所以我尝试通过指定使 DbContextOptions 瞬态:

services.AddDbContext<MainContext>(options => 
                options.UseSqlite("Data Source=development.db"), ServiceLifetime.Transient);

在我的 Startup 课程中。

但是错误仍然是相同的,即使根据 解决的Github问题 ,传递的 DbContextOptions 应该具有 AddDbContext 调用中指定的相同生命周期。

我无法使数据库上下文成为单例,否则对它的并发调用将产生并发异常(由于数据库上下文不保证是线程安全的事实)。


在托管服务中使用服务的一种好方法是在需要时创建范围。 这允许使用服务/ db上下文等,并使用它们设置的生存期配置。 理论上,不创建范围可能会导致创建单例DbContexts和不正确的上下文重用(EF Core 2.0与DbContext池)。

为此,请注入 IServiceScopeFactory 并在需要时使用它来创建范围。 然后解决此范围内所需的所有依赖项。 如果您希望将逻辑移出托管服务并仅使用托管服务触发某些工作(例如,定期触发任务 - 这将定期创建范围,创建任务服务),这也允许您将自定义服务注册为范围依赖项这个范围也会得到一个db上下文注入)。

public class MyHostedService : IHostedService
{
    private readonly IServiceScopeFactory scopeFactory;

    public MyHostedService(IServiceScopeFactory scopeFactory)
    {
        this.scopeFactory = scopeFactory;
    }

    public void DoWork()
    {
        using (var scope = scopeFactory.CreateScope())
        {
            var dbContext = scope.ServiceProvider.GetRequiredService<MyDbContext>();
            
        }
    }
    
}




.net-core