В моем 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;
}
}
Ctor службы выглядит так:
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
и hubConext
- это IHubContext<MyHub, IMyHub>
. Переменная provider
- это IPrincipalProvider
, который был введен в ctor контроллера.
Проблема в том, что когда я пытаюсь разрешить IMyService
в задаче, он создает экземпляр IPrincipalProvider
, и это в свою очередь требует IHttpContextAccessor
, который больше не существует.
Какое решение в этом случае? Нужно ли иметь второй ctor в сервисе с другим IPrincipalProvider
, который получает контекст откуда-то еще? И если это так, откуда?