【问题标题】:Override Lifetime in ASP.NET Core Dependency Injection在 ASP.NET Core 依赖注入中覆盖生命周期
【发布时间】:2017-09-08 07:22:51
【问题描述】:

我已经使用如下标准代码注册了一个实体框架 DBContext:

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

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

但是,我有几个特殊的控制器。他们在超过 Web 请求生命周期的新线程上启动作业。当这些作业使用我的 DbContext(或使用使用我的 DbContext 的服务)时,会引发错误,因为范围内的实例已被释放。

有没有办法只为某些控制器覆盖我注入的 DbContext 的服务生命周期?或者您可以提出其他解决方案吗?

【问题讨论】:

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


    【解决方案1】:

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

    例如:

    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 容器。

    【讨论】:

    • 这听起来不错,我会试一试。谢谢!
    • 本节:simpleinjector.readthedocs.io/en/latest/… 显示了一个 SimpleInjector 示例,其中注入了 Func 以获得 IFoo 工厂。通过这样做,“我们防止应用程序代码依赖于容器本身(应该防止这种情况。)”您是否知道 ASP.NET DI 中的类似功能?只是好奇,我正在继续尝试您的代码示例。
    • @JamesOrr:ASP.NET DI 中不存在此类功能。这是一个非常幼稚的实现,有很多限制。
    • 请问您如何获得对IServiceScopeFactory 的引用?
    猜你喜欢
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多