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

时间:2017-04-12 13:21:53

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

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

public void ConfigureServices(IServiceCollection services)
{
    [...]
    services.AddDbContext<MyDbContextType>(ServiceLifetime.Scoped);
}

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

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

有没有办法覆盖我注入的DbContext的服务生命周期,仅适用于某些控制器?或者你可以建议另一种解决方案吗?

1 个答案:

答案 0 :(得分:8)

您不应该覆盖此行为。相反,您在后台线程上运行的代码应该在自己的范围内运行。这意味着后台线程所做的第一件事就是使用IServiceScope创建一个新的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();

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