HttpClient vs IHttpClientFactory
HttpClient and IHttpClientFactory can be used in .NET to make HTTP requests and handle HTTP responses from web resources. In this article, I explain how to use each of them and what is the difference between them.
For the code samples, I’ve created a .NET 6 Web API project, which makes requests to CoinDesk’s public API. The complete project code can be found here.
HttpClient
HttpClient is a class that can be used for making HTTP requests and handling HTTP responses from web resources identified by a Uri in .NET. The HttpClient type was introduced in .NET Framework 4.5 (which was released in 2012) and is also available in .NET Core and .NET 5+.
Two ways that HttpClient
was commonly used were:
- A new
HttpClient
is created for every single request - The same
HttpClient
is used for all requests
The problem of creating a HttpClient
for each request, is that there is an overhead of instantiation, and beyond that, each HttpClient
will hold open the socket that it used for some time after the request is completed. In case you have made a high volume of requests, you can face a socket exhaustion issue (it’s when a new HttpClient
cannot acquire a socket to make a request). It’s true that when we use the HttpClient
object inside of a using
code block, the HttpClient object is disposed after it is used (because HttpClient
implements IDisposable
), however, the socket connection is not, and this can lead to a socket exhaustion problem when your traffic increases.
A better approach to use HttpClient
, is to create your HttpClient object as singleton or static, instead of wrapping your HttpClient in a using, this way you will have a single instance of HttpClient
for a given endpoint. But even with this approach, it’s better to configure the connection pooling behavior by configuring the PooledConnectionLifetime
(this allows you to define how long a connection remains active when pooled, and once this lifetime expires, the connection will no longer be pooled or issued for future requests — It gets or sets how long a connection can be in the pool to be considered reusable), otherwise if the DNS TTL (time to live — is a setting that tells the DNS resolver how long to cache a query before requesting a new one) is expired and the domain name points to a new IP, your code will never know until it restarts, since there is no default logic in HttpClient
to handle that. In the code below there is an example of how to do that:
On line 6 there is a static property for the HttpClient
, where it is configured the PooledConnectionLifeTime for 1 minute. On line 14 we get the API Url from the appsettings.json
file. On line 21 the request is being made.
The API Url is configured in the appsettings.json
file:
IHttpClientFactory
IHttpClientFactory
was introduced in .NET Core 2.1 (also available in .NET 5+) and it provides a much-improved approach for getting an HTTP client. IHttpClientFactory
can take advantage of resilient and transient-fault-handling third-party middleware with ease. It serves as a factory abstraction that can create HttpClient
instances with custom configurations.
IHttpClientFactory
solves both problems that were previously mentioned in the HttpClient topic, and this is done by pooling the HttpClientHandler
(which does most of the work of HttpClient
) and also dispose of HttpClientHandlers
after a specified period. When a new HttpClientHandler
is created for an endpoint, A DNS lookup is performed, with that you won’t wear out the sockets and you will get a new IP address for each endpoint.
How to use
The first thing that must be done in order to use IHttpClientFactory
, is to register it by calling AddHttpClient
via Dependency Injection (it will be registered in the service collection as a singleton). In the Program.cs file, you can register like this:
Once registered, now the class that will make use of IHttpClientFactory
can receive it as a constructor parameter with DI. In the code below there is an example of how to use it:
Note that on line 8, IHttpClientFactory
is part of the constructor parameter, and we have a private variable to be used in this class. On line 11 we get the API Url from the appsettings.json file. On line 19 there is a call to CreateClient
, this is a IHttpClientFactory
method which returns the HttpClient Object. On line 22 the request is executed.
Named Clients
It’s also possible to have named clients, you can do that by registering it via DI (you can register how many you want). This is how you can configure it in a Program.cs file:
This is how you can use the named client in your class:
As in the previous example, IHttpClientFactory
is part of the constructor parameter, and we have a private variable to be used in this class (line 3). On line 14 there is a call to CreateClient
, but now with the name that was configured via DI. On line 16 the request is executed.
There are also other ways to work with IHttpClientFactory
, if you want to know more about it, check the Consumption patterns at Microsoft Docs.
IHttpClientFactory Benefits
- Exposes
HttpClient
class as DI ready type. - Provides a central location for naming and configuring logical
HttpClient
instances. - Integrates well with Polly (a .NET resilience and transient-fault-handling library).
- Avoid common DNS problems by managing HttpClientHandler lifetimes.
- Adds configurable logging (via
ILogger
) for all the requests sent through clients created by the factory.
For most cases, the best approach for making requests to external API is by using IHttpClientFactory. Microsoft’s recommendation is to use IHttpClientFactory or use a static or singleton HttpClient with PooledConnectionLifetime configured with the desired interval. You can check the complete code of this project here:
https://github.com/henriquesd/HttpRequestExamples
If you like this project, I kindly ask you to give a ⭐️ in the repository.
Thanks for reading!
References
Tutorial: Make HTTP requests in a .NET console app using C# — Microsoft Docs
IHttpClientFactory In .NET Core To Avoid Socket Exhaustion — C# Corner
Make HTTP requests using IHttpClientFactory in ASP.NET Core — Microsoft Docs
Guidelines for using HttpClient — Microsoft Docs
IHttpClientFactory Interface — Microsoft Docs
Use IHttpClientFactory to implement resilient HTTP requests — Microsoft Docs
You’re using HttpClient wrong and it is destabilizing your software — ASP.NET Monsters
Fault Tolerant Web Service Requests with Polly — Bryan Hogan — Pluralsight
HttpClient Connection Pooling in .NET Core — Steve Gordon
Stop using the HttpClient the wrong way in .NET — Nick Chapsas
Using HttpClient in .NET Core to Connect to APIs in C# — IAmTimCorey