在ASP.NET核心依赖注入中覆盖生命周期

Jam*_*Orr 5 c# dependency-injection asp.net-core

我使用标准代码注册了一个Entity Framework DBContext,如下所示:

public void ConfigureServices(IServiceCollection services)
{
    [...]
    services.AddDbContext<MyDbContextType>(ServiceLifetime.Scoped);
}
Run Code Online (Sandbox Code Playgroud)

这对于需要EF服务的控制器调用的服务非常有用.

但是我有几个特殊的控制器.它们在运行超过Web请求生命周期的新线程上启动作业.当这些作业使用我的DbContext(或使用使用我的DbContext的服务)时,会抛出错误,因为已经处理了作用域实例.

有没有办法覆盖我注入的DbContext的服务生命周期只是为了某些控制器?或者您可以建议另一种解决方案吗?

Ste*_*ven 8

您不应该覆盖此行为.相反,您在后台线程上运行的代码应该在自己的范围内运行.这意味着后台线程所做的第一件事是IServiceScope使用the 创建一个新的IServiceScopeFactory.在此范围内,您可以解析要使用的服务并调用该服务.在操作结束时,您将处置您的示波器.

例如:

private IServiceScopeFactory factory;

new Thread(() => 
{
    using (var scope = this.factory.CreateScope())
    {
        // Resolve
        var service = scope.ServiceProvider.GetRequiredService<IService>();

        // Use
        service.DoStuff();

        // Dispose scope
    }
}).Start();
Run Code Online (Sandbox Code Playgroud)

有关在多线程应用程序中使用DI的更多信息,请查看此文档.虽然文档是针对特定的DI容器编写的,但它本质上是通用的,并且建议也适用于您的DI容器.