Использование фабричного метода для создания типизированного HTTP-клиента, ASP.NET Core 2.1 - PullRequest
0 голосов
/ 09 февраля 2019

Я следую инструкциям / документам по регистрации HTTP-клиента в моем приложении.Мне нужно позвонить в несколько служб, поэтому я решил использовать «Типизированные клиенты».

Для вызова другой службы мне нужно использовать OAuth - так как это вызов службы, когда яполучить токен доступа, я кеширую его + у меня настроено периодическое обновление токена.Это означает, что есть еще один компонент IAccessTokenCache, который дает мне токен доступа для службы.

Я пытаюсь выяснить, как зарегистрироваться и настроить мой типизированный HTTP-клиент, при условии, что он также зависит от IAccessTokenCache.

Я использую ASP.NET Core 2.1 (важная деталь, читайте дальше).

Оболочка HTTP-клиента выглядит следующим образом (из: HttpClientFactory в ASP.NET Core 2.1 (часть 2)) ):

public class ServiceFooClient
{
    public ServiceFooClient(HttpClient client)
    {
        Client = client;
    }

    public HttpClient Client { get; }
}

И вот как я регистрирую и настраиваю клиента:

services
    .AddHttpClient<ServiceFooClient>(
        c =>
        {
            c.BaseAddress = new Uri("https://www.foo.svc");

            // TODO: grab particular access token from cache
            c.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "...");
        })
    .AddHttpMessageHandler<ResponseMonitorHandler>()
    .ConfigureHttpMessageHandlerBuilder(
        b =>
        {
            var handler =
                b.AdditionalHandlers.OfType<ResponseMonitorHandler>().FirstOrDefault();

            if (handler != null)
            {
                handler.ServiceName = "Foo Service";
            }
        });

... Я уже настраиваю HTTP-клиента и даже добавляю свой собственный HTTPобработчик.Вы можете видеть точную точку, где я хочу получить доступ к IAccessTokenCache, но не могу.

Возможные решения, которые я могу придумать:

Конфигурировать базовую HttpClient в ServiceFooClient оболочку,как:

// ctor
public ServiceFooClient(HttpClient httpClient, IAccessTokenCache tokenCache)
{
    Client = httpClient;
    Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenCache.GetToken("Foo"));
}

Это могло бы работать хорошо, за исключением того, что я не разделяю конфигурацию - внезапно выделенный HTTP-клиент имеет часть конфигурации в Startup (базовый URI, дополнительный обработчик HTTP) и другую часть в классе упаковки(настройка заголовка авторизации).

Не использовать AddHttpClient метод расширения (и другие)

Мне не нужно вызывать HttpClientFactoryServiceCollectionExtensions.AddHttpClient<T>(...) - я мог бы сам делать все это.Но как ленивый разработчик ... я даже не хочу заканчивать это предложение.Внутри довольно много регистрации, так что для меня это просто нет, нет.

Обновление до ASP.NET Core 2.2

По предыдущему пункту - в 2.1 нет перегрузки AddHttpClient (2.2: AddHttpClient<TClient>(this IServiceCollection services, Action<IServiceProvider, HttpClient> configureClient)), который будет принимать обратный вызов с поставщиком услуг.Обновление до 2.2 было бы, вероятно, лучшим решением, но я должен быть уверен, что больше ничего не сломается (и я уже знаю, что есть / был разрыв BC с получением / настройкой идентификатора трассировки запроса в контексте HTTP).Это может быть потенциально рискованно, поэтому я сначала пытаюсь решить мою проблему в области 2.1.

Сравнить ветку 2.1 с 2.2: HttpClientFactoryServiceCollectionExtensions

Пользовательский обработчик HTTPустановка заголовков запросов

Так же, как я сейчас регистрирую ResponseMonitorHandler, я мог бы зарегистрировать обработчик HTTP, который имеет доступ к IAccessTokenCache и устанавливает заголовок авторизации запроса.

Но, опять же, как в первом случаеэто разъединяет конфигурацию HTTP-клиента.Кроме того, если бы у меня было несколько разных токенов доступа, мне нужно было бы реализовать несколько обработчиков HTTP или сделать некоторую логику, чтобы решить, какой токен из кэша использовать на основе свойств запроса.

Наконец, вопрос :Есть ли другой способ, который я не учел?Есть ли простое решение этого в ASP.NET 2.1?(... кроме просто метода копирования-вставки из 2.2, конечно)

1 Ответ

0 голосов
/ 13 февраля 2019

Очевидно, есть еще один метод расширения в 2.1 ConfigureHttpClient(IHttpClientBuilder, Action<IServiceProvider,HttpClient>), который делает именно то, что мне нужно!

...