我使用标准代码注册了Entity Framework DBContext,如下所示:
public void ConfigureServices(IServiceCollection services)
{
[...]
services.AddDbContext<MyDbContextType>(ServiceLifetime.Scoped);
}
这对于需要EF服务的控制器调用的服务非常有用。
但是我有几个特殊的控制器。它们在运行超过Web请求生命周期的新线程上启动作业。当这些作业使用我的DbContext(或使用使用我的DbContext的服务)时,会抛出错误,因为已经处理了作用域实例。
有没有办法覆盖我注入的DbContext的服务生命周期,仅适用于某些控制器?或者你可以建议另一种解决方案吗?
答案 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容器。