在我的ASP.Net Core 3.1 Webapi中,我将
IHttpContextAccessor
注册为单例并注入到所有控制器中。我有一个接口也被注入到所有的控制器和服务中(这些服务连接到数据库)。该接口的实现如下:public class PrincipalProvider : IPrincipalProvider
{
private readonly UserPrincipal principal;
public PrincipalProvider(IHttpContextAccessor accessor)
{
accessor.HttpContext.Items.TryGetValue("principal", out object principal);
this.principal = principal as UserPrincipal;
}
public UserPrincipal GetPrincipal()
{
return principal;
}
}
一个服务的构造函数如下:
public MyService(
IPrincipalProvider provider,
ILogger<MyService> logger,
IUnitOfWork unitOfWork) : base(provider, logger, unitOfWork)
{ }
只要我在请求上下文中,以上所有内容都能正常工作。
我有一个控制器操作,使用具有后台队列的新IHostedService
实现启动后台任务,并且它是这样启动的:
backgroundQueue.QueueBackgroundWorkItem(async (scope, hubContext, ct) =>
{
await hubContext.Clients.Client(provider.GetPrincipal().ConnectionId).Notify();
var myService = scope.Resolve<IMyService>();
}
scope
是ILifetimeScope
,而hubContext
是IHubContext<MyHub, IMyHub>
。变量provider
是注入到控制器构造函数中的IPrincipalProvider
。
问题在于,在任务中尝试解析IMyService
时,它会创建IPrincipalProvider
的一个实例,而该实例要求的IHttpContextAccessor
不再存在。
这种情况下的解决方案是什么?我需要在服务上有第二个构造函数,使用不同的IPrincipalProvider
,从其他位置获取上下文吗?如果是这样,那从哪里获取呢?
ILifetimeScope
注入到构造函数中,然后创建一个子作用域,并在其中包装任务来解决这个问题。但是问题仍然存在,因为 DbContext 也被释放了。 - Ivan-Mark DebonoIHttpContextAccessor
本身是一个单例,因此它存在于应用程序的整个生命周期中。但它从请求Task
的环境数据中读取HttpContext
。请求完成后,上下文也会消失。 - weichch