.Net Core — Доступ к службе с областью действия в HttpMessageHandler без HttpContext — Не удается получить службу с областью действия от корневого поставщика

#c# #.net #asp.net-core #.net-core #dependency-injection

#c# #.net #asp.сетевое ядро #.net-ядро #инъекция зависимости

Вопрос:

Я не могу получить доступ к службе с областью действия из HttpMessageHandler, подключенного к HttpClient.

Вот как был настроен обработчик аутентификации, и я проверил, что он вызывается для каждого запроса на HttpClient

 services.AddScopedlt;IDataService, DataServicegt;(); builder.HttpClientBuilder.AddHttpMessageHandler(AuthenticationHandler); builder.Services.AddTransientlt;AuthenticationHandlergt;();  

У меня также подавлена область обработчика, чтобы обработчик не использовал свою собственную область SuppressHandlerScope = true

Проблема теперь возникает внутри HttpMessageHandler, где я хочу внедрить службу IDataService с областью действия

 public class AuthenticationHandler : HttpMessageHandler {  private readonly IDataService _dataService;  public AuthenticationHandler(IDataServie dataService){  _dataService = dataService;  }   protected override Tasklt;HttpResponseMessagegt; SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)  {  var token = _dataService.GetAccessToken(); // Error: cannot access scoped service from root provider  if(!string.IsNullOrEmpty(token){  // if a data service with a token was scoped to this request, set it to the Http Header...  }   return base.SendAsync(request, cancellationToken);  } }  

Теперь единственный способ разрешить _dataService здесь-это зарегистрировать IDataService как одноэлементный, но это невозможно сделать. Я хочу иметь возможность устанавливать значение области действия только в том случае, если мне нужно изменить токен аутентификации во время выполнения.

итак, вот как это использовалось.

 public class Foo() {  public Foo(IServiceProvider serviceProvider)  {  using(var scope = serviceProvider.CreateScope())  {   // For this specific request i want to inject a different token specific to just this request, so i overwrite the existing request using the data Service.  // I cannot access the HttpClient of the service directly so it needs to be achieved through a handler  var dataService = scope.ServiceProvider.GetRequiredServicelt;IDataServicegt;();  dataService.SetAccessToken("SomeToken");  _serviceHttpClient.doSomeHttpRequest();  }  } }  

В этом случае я создал область, установил значение маркера службы данных и затем сделал запрос. Почему HttpMessageHandler не может использовать экземпляр службы данных, для которого он был определен? Я все еще получаю проблему «не удается получить службу с областью действия от корневого поставщика».

Это даже в том случае, если я не буду напрямую вводить IDataService, но в лицо введу IServiceProvider и получу доступ к службе внутри обработчика var dataService = scope.ServiceProvider.GetRequiredServicelt;IDataServicegt;() , как так, возможно ли это вообще без использования синглтона?

Все эти запросы выполняются в фоновой задаче, удаленной из очереди, поэтому нет исходных областей или HttpRequestContext, доступных для получения службы с областью действия.

Комментарии:

1. Вы имеете в виду, что хотите получить HttpMessageHandler, который вы зарегистрировали в program.cs при запуске фоновой задачи?