#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 при запуске фоновой задачи?