编辑摘要
我有一个后台服务,需要DBContext。我的DbContext依赖于HttPContext,因为它使用UserClaims来过滤上下文。但是,在从BackgroundService请求DbContext时,HttpContext为空(这是出于设计考虑,因为BackgroundService没有关联的WebRequest)。
如何捕获和模拟HTTPContext,以便我的用户声明可以传递到后台服务?
我正在编写一个托管服务,将在Signalr中推送信息。我的Background。
public interface IBackgroundTaskQueue
{
void QueueBackgroundWorkItem(Func<IServiceProvider, CancellationToken, Task> workItem);
Task<Func<IServiceProvider, CancellationToken, Task>> DequeueAsync(CancellationToken cancellationToken);
}
public class BackgroundTaskQueue : IBackgroundTaskQueue
{
private ConcurrentQueue<Func<IServiceProvider, CancellationToken, Task>> _workItems = new ConcurrentQueue<Func<IServiceProvider, CancellationToken, Task>>();
private SemaphoreSlim _signal = new SemaphoreSlim(0);
public void QueueBackgroundWorkItem(Func<IServiceProvider, CancellationToken, Task> workItem)
{
if (workItem == null)
{
throw new ArgumentNullException(nameof(workItem));
}
this._workItems.Enqueue(workItem);
this._signal.Release();
}
public async Task<Func<IServiceProvider, CancellationToken, Task>> DequeueAsync(
CancellationToken cancellationToken)
{
await this._signal.WaitAsync(cancellationToken);
this._workItems.TryDequeue(out var workItem);
return workItem;
}
}
我正在排队处理需要使用 DbContext 的工作项,我的 DbContext 会根据已登录的用户自动过滤数据,因此需要访问 HTTPContextAccessor。
当我排队处理需要使用 DbContext 的项目时,出现了 HTTPContext 为空的错误,这是有道理的,因为我正在后台进程中运行。
var backgroundTask = sp.GetRequiredService<IBackgroundTaskQueue>();
backgroundTask.QueueBackgroundWorkItem((isp, ct) => {
//When this line is executed on the background task it throws
var context = sp.GetService<CustomDbContext>();
//... Do work with context
});
我的DBContext使用HTTPContextAccessor来过滤数据:
public CustomDbContext(DbContextOptions options, IHttpContextAccessor httpContextAccessor)
{
}
有没有办法在每个任务中捕获HTTPContext,或者Moq它并捕获UserClaims,并将它们替换为BackgroundService的范围内?
我如何从我的后台服务中使用依赖于HTTPContext的服务。