Поделиться HttpClient между сервисами - PullRequest
1 голос
/ 20 апреля 2020

Я работаю над проектом Blazor, и чтобы облегчить понимание вопроса, можно сказать, что я использую два разных сервиса, которые обрабатывают часть аутентификации. Они регистрируются в методе запуска configureservices вместе с именованным httpclient.

services.AddHttpClient("XBOWServicesApi", c =>
{
c.BaseAddress = new Uri(XBOWServicesApi);
});

services.AddSingleton<IService1, Service1>();
services.AddSingleton<IService2, Service2>();

Служба 1: охватывает все функции, доступные в REST Api. Он использует http-клиент, который устанавливается в конструкторе через экземпляр httpclientfactory. Это должно быть установлено с помощью baseurl и заголовка Auth для работы.

public Service1(IHttpClientFactory clientFactory)
{
this.httpClient = clientFactory.CreateClient("XBOWServicesApi");
}

Служба 2: обрабатывает функцию входа / выхода из системы с использованием пользовательского AuthenticationStateProvider. У него есть собственный httpclient, так что я могу установить заголовок аутентификации для http-клиента. Конструктор работает так же, как и для Сервиса 1.

public Service2(IHttpClientFactory clientFactory)
{
this.httpClient = clientFactory.CreateClient("XBOWServicesApi");
}

Причина такой сборки, конечно, в том, что мне нравится использовать один и тот же http-клиент, поэтому, когда он задан при входе / выходе из системы Методы, служба 1 будет иметь правильный заголовок аутентификации при взаимодействии с API.

Однако фабрика клиентов предоставляет новый экземпляр каждый раз, так что это никогда не будет работать.

Любые идеи, как обращаться это?

/ Хенрик

Ответы [ 3 ]

0 голосов
/ 20 апреля 2020

Вы можете использовать named client:

services.AddHttpClient("github", c =>
{
    c.BaseAddress = new Uri("https://api.github.com/");
    // Github API versioning
    c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
    // Github requires a user-agent
    c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
});

После этого просто вызовите метод CreateClient с соответствующим параметром name.

var client = _clientFactory.CreateClient("github");

Каждый раз, когда вызывается CreateClient :

  • Создан новый экземпляр HttpClient.
  • Вызывается действие конфигурации.

Более подробную информацию можно найти в документации Microsoft здесь .

0 голосов
/ 20 апреля 2020

Вы можете обмениваться сервисами с областью действия между временными HttpClients, используя HttpMessageHandlers.

IHttpClient.CreateClient каждый раз возвращает новый экземпляр, но вы можете зарегистрировать HttpMessageHandler, как показано ниже:

services.AddScoped<HandlerData>();
services.AddTransient<HeaderHandler>();
services.AddHttpClient("XBOWServicesApi", c =>
{
c.BaseAddress = new Uri(XBOWServicesApi);
}).AddHttpMessageHandler<HeaderHandler>();

Класс HeaderHandler:

public class HeaderHandler : DelegatingHandler
{
    private readonly IHttpContextAccessor httpContextAccessor;
    public HeaderHandler(IHttpContextAccessor httpContextAccessor)
    {
        this.httpContextAccessor = httpContextAccessor;
    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken )
    {
        var Data= this.httpContextAccessor.HttpContext.RequestServices.GetRequiredService<HandlerData>();
        request.Headers.Add(Data.HeaderName, Data.HeaderValue);
        return base.SendAsync(request, cancellationToken);
    }
}

Класс HandlerData:

public class HandlerData
{
    public string HeaderName { get; set; }
    public string HeaderValue { get; set; }
}

Код службы:

public Service1(IHttpClientFactory clientFactory, HandlerData data)
{
    data.HeaderName = "Header1";
    data.HeaderValue = "Value";
    this.httpClient = clientFactory.CreateClient("XBOWServicesApi");
}
public Service2(IHttpClientFactory clientFactory)
{
    //This will contain the same headers as Service1 as HandlerData is Scoped Service
    this.httpClient = clientFactory.CreateClient("XBOWServicesApi");
}

Кроме того, вы также можете использовать новый IHttpMessageHandlerFactory, если вам нужно создать обработчики, которые находятся в той же области DI, что и вы:

Ссылка: https://github.com/aspnet/HttpClientFactory/issues/166

0 голосов
/ 20 апреля 2020

Когда я читаю документы Microsoft IHttpClientFactory :

Каждый раз, когда вы получаете объект HttpClient из IHttpClientFactory, возвращается новый экземпляр. Но каждый HttpClient использует HttpMessageHandler, который объединяется и используется IHttpClientFactory для сокращения потребления ресурсов, пока не истек срок службы HttpMessageHandler.

Отвечает ли это на ваш вопрос?

...