EDIT Summary
I have a background service, which requires a DBContext, my DbContext is dependent on the HttPContext, because it uses the UserClaims to filter the context. The HttpContext which is null when requesting the DbContext from BackgroundService, (this is by design because there is no WebRequest associated with a BackgroundService).
How can I capture and moq the HTTPContext, so my user claims will carry over to the background service?
I'm writing a hosted service to queue pushing messages from my Hubs in Signalr. My 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;
}
}
I'm queue work items that require my DbContext, My Db Context automatically filters data based off the logged in user, So it requires access to the HTTPContextAccessor.
When I Queue up an Item that requires my DbContext, I get an error the the HTTPContext is null, which makes sense because, I'm running in a background process.
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
});
My DBContext uses the HTTPContextAccessor to filter data:
public CustomDbContext(DbContextOptions options, IHttpContextAccessor httpContextAccessor)
{
}
Is there a way I can capture the HTTPContext with each Task, or perhaps Moq one and capture the UserClaims, and replace them in the scope for the BackgroundService?
How can I use services dependent on HTTPContext from my background services.