2

I have a class into which the IHttpClientFactory is injected via the constructor. There's also a HttpClient private field in this class.

Are there any issues with creating the HttpClient in the constructor, using the factory, and then reusing that HttpClient in two/multiple methods within that one class to make two/multiple different api calls? (Same Api, different endpoints)

Or would it be better to use the factory in each method to create a new client. What are the implications/pros & cons of each approach? Is any one inherently better or doesn't it matter?

private readonly HttpClient _httpClient;

public RestClient(IHttpClientFactory httpClientFactory)
{
   _httpClient = httpClientFactory.CreateClient();
}

public async Task<SomeResponse> Method1(SomeRequest request)
{
    ...

        using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, url))
        {
             httpRequestMessage.Headers.Add("Accept", "application/json");
                    httpRequestMessage.Headers.Add("Authorization", "Basic " + credentials);
                    httpRequestMessage.Content = new StringContent(jsonBody, Encoding.UTF8, "application/json");

            using (var response = await _httpClient.SendAsync(httpRequestMessage))
            {
                ...
            }
        }
...
}

public async Task<SomeOtherResponse> Method2(someInput)
{
   ...

        using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri.ToString()))
        {
            httpRequestMessage.Headers.Add("Accept", "image/png");
            httpRequestMessage.Headers.Add("Authorization", "Basic " + credentials);

            using (var response = await _httpClient.SendAsync(httpRequestMessage))
            {
                ...
            }
        }
...
}


Edit: have looked at this post Should I cache and reuse HttpClient created from HttpClientFactory? but it doesn't answer my questions. If there is something to be derived from there please explain.

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
imsan
  • 359
  • 4
  • 17
  • 2
    Does this answer your question? [Should I cache and reuse HttpClient created from HttpClientFactory?](https://stackoverflow.com/questions/54597303/should-i-cache-and-reuse-httpclient-created-from-httpclientfactory) – Dimitris Maragkos Sep 27 '22 at 12:33
  • No still don't understand if it's okay to create the httpClient in the constructor and reuse it, the example in the Basic usage (https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.2) only has one method in the class and it creates the httpClient in that. – imsan Sep 27 '22 at 15:36
  • 3
    It is ok to create the `HttpClient` in the constructor and reuse it. – Dimitris Maragkos Sep 27 '22 at 16:09
  • 2
    I think it is okay to use the factory to create new clients when you need them (not disagreeing with the above - just saying I don't see a problem using the client factory whenever you need a client). It is difficult to say if one is better than the other. I prefer to use the client factory because this is what MS recommends (at least for now - until they change their mind again). I don't see any cons that way. – topsail Sep 27 '22 at 16:11
  • Having looked at the attached link again, it's relevance now makes sense. Thanks – imsan Oct 10 '22 at 15:46

1 Answers1

1

I think you are looking for this guidance from Microsoft: Guidelines for using HttpClient

I copy here the related part

Recommended use

In .NET Core and .NET 5+:

Use a static or singleton HttpClient instance with PooledConnectionLifetime set to the desired interval, such as two minutes, depending on expected DNS changes. This solves both the socket exhaustion and DNS changes problems without adding the overhead of IHttpClientFactory. If you need to be able to mock your handler, you can register it separately.

Using IHttpClientFactory, you can have multiple, differently configured clients for different use cases. However, be aware that the factory-created clients are intended to be short-lived, and once the client is created, the factory no longer has control over it.

The factory pools HttpMessageHandler instances, and, if its lifetime hasn't expired, a handler can be reused from the pool when the factory creates a new HttpClient instance. This reuse avoids any socket exhaustion issues.

If you desire the configurability that IHttpClientFactory provides, we recommend using the typed-client approach.

In .NET Framework:

Use IHttpClientFactory to manage your HttpClient instances. If you create a new client instance for each request, you can exhaust available sockets.

Tip

If your app requires cookies, consider disabling automatic cookie handling or avoiding IHttpClientFactory. Pooling the HttpMessageHandler instances results in sharing of CookieContainer objects. Unanticipated CookieContainer object sharing often results in incorrect code.

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
  • 1
    "However, be aware that the factory-created clients are intended to be short-lived" this is what I was looking for, I take this to mean that while they CAN be reused, probably shouldn't be too many times. Can anyone expand on this/exactly why this is? Thank you for posting the relevant snippet, easy to miss in a long article. – imsan Oct 10 '22 at 15:37
  • 1
    @imsan The Factory itself manages a handler pool. A handler can be used by only a single instance of HttpClient. If your HttpClient instances are short-lived then the underlying handlers could be reused for new instances. – Peter Csala Oct 10 '22 at 16:04
  • 1
    @imsan If you are interested about the internals [here](https://stackoverflow.com/a/73838672/13268855) you can read more about them. – Peter Csala Oct 10 '22 at 16:08