Могу ли я всегда создавать новый экземпляр IHttpClientFactory, даже если я могу использовать экземпляр дважды или более?

#c# #.net-core #httpclient

#c# #.net-core #httpclient

Вопрос:

Я написал WebAPI в .NET Core и использовал IHttpClientFactory для создания HttpClients. Я настроил его при запуске.cs в ConfigurationServices.

 services.AddHttpClient("ITSMServiceClient", m =>
            {
                m.DefaultRequestHeaders.Accept.Clear();
                m.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
            }).SetHandlerLifetime(TimeSpan.FromMinutes(10))
            .ConfigurePrimaryHttpMessageHandler(() =>
            {
                var handler = new HttpClientHandler()
                {
                    AllowAutoRedirect = false,
                    UseCookies = false
                };

                // Отключаем проверку валидности http-сертификата (если необходимо)
                handler.ClientCertificateOptions = ClientCertificateOption.Manual;
                handler.ServerCertificateCustomValidationCallback =
                               (httpRequestMessage, cert, cetChain, policyErrors) => true;

                return handler;
            });
  

Затем я использую его в одном dataProvider через DI.

 private readonly IHttpClientFactory _clientFactory;

        public ExecuteDataProvider(IHttpClientFactory clientFactory)
        {
            _clientFactory = clientFactory;
        }
  

Я использую методы этого поставщика для всех отправляющих запросов

 public async Task<HttpResponseMessage> PostAsync(HttpRequestMessage request)
        {
            using (var client = _clientFactory.CreateClient("ITSMServiceClient"))
            {
                return await client.SendAsync(request);
            }
        }
  

И у меня есть вопрос. Это нормальное поведение — всегда получать новый экземпляр из _clientFactory, даже если я могу повторно использовать экземпляр дважды или более в коде?
Все мои dataProvider и другие объекты описываются как singleInstance в DI.

 builder.RegisterType<ExecuteDataProvider>().As<IExecuteDataProvider>().SingleInstance();
  

Теперь я использую его примерно так:

 var request = CreatePostRequest(url, parameters, jParameters, checkingToken);

HttpResponseMessage httpResponseMessage = await _executeCoreDataProvider.PostAsync(request);
if (await CheckingForUnauthorizedToken(httpResponseMessage, checkingToken))
{
        request = CreatePostRequest(url, parameters, jParameters, checkingToken);
        httpResponseMessage = await _executeCoreDataProvider.PostAsync(request);
}
response = await httpResponseMessage.Content.ReadAsStringAsync();
httpResponseMessage.Dispose();
  

И я беспокоюсь о том, чтобы дважды получить HttpClient. Это нормально или использовать один экземпляр client будет правильнее?

Я уже читал о ClientFactory в документах Microsoft; это, а также некоторые другие сайты.

Ответ №1:

В рамках одного запроса обычно используется только один HttpClient . Однако, если это проще, вы можете получить несколько экземпляров из IHttpClientFactory . Сам HttpClient по себе это всего лишь тонкая оболочка, поэтому несколько экземпляров не оказывают большого влияния. Важной частью является то, что эти экземпляры поступают из IHttpClientFactory , который разделяет HttpMessageHandler между несколькими HttpClient экземплярами.

Единственная необычная часть вашего кода — это using оператор; как правило, HttpClient экземпляры не удаляются (это все еще верно в IHttpClientFactory мире). Но это удаление не плохо; просто немного необычно.

Документы: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.1#httpclient-and-lifetime-management

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

1. Спасибо, Стивен! Я думал то же самое, но мне действительно нужно было услышать мнение.

2. Обновленная ссылка «Экземпляры HttpClient обычно можно рассматривать как объекты .NET, не требующие удаления. Удаление отменяет исходящие запросы и гарантирует, что данный экземпляр HttpClient не может быть использован после вызова Dispose . IHttpClientFactory отслеживает и распоряжается ресурсами, используемыми экземплярами HttpClient »