1

I wrote a WebAPI in .NET Core and used IHttpClientFactory for creating httpClients. I customized it on Startup.cs in 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;
            });

Then I use it in one dataProvider via DI.

private readonly IHttpClientFactory _clientFactory;

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

I use methods of this provider for all sending requests

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

And I have a question. Is it normal behavior always get new instance from _clientFactory even if I can reuse instance twice or more in code? All my dataProvider and another entyties describe like SingleInstance in DI.

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

Now I use it something like this:

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();

And I worry about twice getting HttpClient. Is it normal or use one instance of client will be more correctly?

I've already read about ClientFactory on Microsoft Docs; this, and also some other sites.

0

1 Answer 1

5

In the scope of a single request, it's normal to use just one HttpClient. However, if it's easier, you can get multiple instances from the IHttpClientFactory. The HttpClient itself is just a thin wrapper, so multiple instances don't have a big impact. The important part is that these instances are coming from the IHttpClientFactory, which shares the HttpMessageHandler between multiple HttpClient instances.

The only unusual part to your code is the using statement; generally, HttpClient instances are not disposed (this is still true in the IHttpClientFactory world). But this disposal isn't bad; just a bit unusual.

Docs: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.1#httpclient-and-lifetime-management

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you Stephen! I've thought the same, but I really had to heard an opinion.
Updated link "HttpClient instances can generally be treated as .NET objects not requiring disposal. Disposal cancels outgoing requests and guarantees the given HttpClient instance can't be used after calling Dispose. IHttpClientFactory tracks and disposes resources used by HttpClient instances"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.