HTTP Client Factory with .NET Core 2.1

The HttpClient class can be easily used in a way how it’s not meant to be. While this class is disposable, using it with the using statement is often not the best choice. Disposing the HttpClient, the underlying socket is not immediately released. The HttpClient class is designed to be reused for multiple requests. Having the need for different base addresses, different HTTP headers, and for error recovery, it helps having multiple instances.
To make the management of HttpClient instances easier, .NET Core 2.1 offers a new HTTP Client Factory – which creates, caches, and disposes HttpClient instances. This article demonstrates different ways on using the IHttpCientFactory.

Networking

Why it’s not a good idea to use the HttpClient class with the using statement is clearly demonstrated with this blog article from Simon Timms.

Using the IHttpClientFactory

To get rid of self-creating of HttpClient instances, after adding the NuGet package Microsoft.Extensions.Http, the extension method AddHttpClient for IServiceCollection is available. This extension method registers the DefaultHttpClientFactory to be used as a singleton for the interface IHttpClientFactory. It defines a transient configuration for the HttpMessageHandlerBuilder. This message handler is used by the HttpClient returned from the factory.

You can call AddHttpClient multiple times – with different configurations. The sample code defines the name cni for HttpClients using the base address https://www.cninnovation.com. You can also add HTTP headers that should be used with all the HttpClient instances from this group.

With the class where the HttpClientshould be used, the IHttpClientFactory is injected in the constructor. From there, the HttpClient is retrieved by invoking the CreateClient method of this interface. Depending on the different HttpClient instances needed, the HttpClient can be retrieved in the constructor of the class, or in the method where the HttpClient is used. You don’t need to deal with the HTTP headers needed, or the base address – just the name of the registration needs to be used invoking the CreateClient method to get the HttpClient with the correct configuration.

Disposing of the HttpClient can be done, but is not required. Disposing of the HttpClient cancels any outgoing request and ensures that the HttpClient cannot be used after disposing. The factory itself tracks, caches, and disposes resources used by the HttpClient, that’s why disposing is not required.

Using a Typed Client

Another way on using the factory is by using a typed client. A typed client makes use of a HttpClient with a specific configuration, and the HttpClient is injected in the constructor. With the following code snippet, in the TypedClient class, the HttpClient is injected in the constructor, and used like before in the CallServerAsync method.

With the dependency injection container configuration, now the method AddTypedClient is invoked passing the TypedClient class. This is an extension method for the IHttpClientBuilder interface, and thus can be used with the return value of the AddHttpClient method. This way, the configuration of the HttpClient maps to the typed client.

Using Polly

With this factory, The Polly Project can be used to handle faults. The NuGet package Microsoft.Extensions.Http.Polly offers extension methods to use Polly with the factory.
Using the IHttpClientBuilder returned from the method AddHttpClient, policies can be defined. Invoking the method AddPolicyHandler passing the Policy.TimoutAsync policy, the timout can be specified used by the HttpClient.
The method AddTransientHttpErrorPolicy deals with transient errors – network failures and HTTP 5xx and HTTP 408 errors. The code sample makes use of the wait and retry policy and passes three different timespans – 1, 5, and 10 seconds. If a transient error occurs, a retry is done after 1 second. If the error still happens after 1 second, retries happen after 5 and 10 seconds. If the error still happens after 10 seconds, an exception is thrown that is dealt with when using the HttpClient.

The Polly Project offers rich policies to handle errors.

Using a HttpClientHandler

The HTTP Client Factory offers a lot ways for customization. One way is to add a HttpClientHandler that you are used to pass to the constructor of the HttpClient with the HttpMessageHandler constructor.

To define to use a HttpClientHandler, you just need to invoke the method ConfigureHttpMessageHandlerBuilder, and return a HttpClientHandler from the implemention of the delegate parameter. Here, you can configure the HttpClientHandler, e.g. with automatic decompression:

Summary

The HTTP Client Factory fixes issues on using the HttpClient and make it easy to use it with different configurations needed – including policies to specify retry logic on errors. Using the HttpClient, it just needs to be injected in the classes where you need this type. Microsoft.Extensions.Http gives you extension methods to integrate with the .NET Core dependency injection container, and Microsoft.Extensions.Http.Polly offers an integration to the Polly Project.

The complete Source code is available at Github.

More information on Network programming with .NET Core in my book Professional C# 7 and .NET Core 2.0 and with my trainings.

Enjoy coding!
Christian

If you found this information valuable and want to return me a favor, then buy me a coffee.

Buy Me A Coffee

Advertisements

5 thoughts on “HTTP Client Factory with .NET Core 2.1

  1. Thanks for the article Christian.

    I want to use the HttpClientFactory but I also want to use the HttpClientHandler to utilize the AutomaticDecompression.

    I am struggling because the .AddHttpMessageHandler takes a DelegatingHandler not a HttpClientHandler.

    Any ideas how to use both the factory and be HttpClientHandler?

    Thanks,
    Jim

    Liked by 1 person

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.