As we reported back in 2016, .NET's HttpClient has some serious issues. With the introduction of HttpClientFactory in .NET Core 2.1, some of those issues have been mitigated.

The fundamental problem with HttpClient is that it looks like a per-call resource that should be disposed immediately after use. In actuality, it is meant to be created once per destination server and kept for the life of the application. Except when it's not, such as when needing to clear the DNS cache.

The new HttpClientFactory allows you to pre-configure HttpClients on application startup. Each configuration is named, making it easier to request a HttpClient with the correct configuration. An unnamed configuration is also provided for cases where custom configuration isn't needed.

Because strings can be error prone, the configuration for an HttpClient can also be keyed to a specific type. For example, you can create a configuration for the GitHubService class. Then the Dependency Injection (DI) framework will ensure that instances of GitHubService will be provided with a HttpClient using that configuration rather than the default.

This new framework for managing HttpClients does not change the basic rules for their use: it is still dangerous to dispose an HttpClient. In regards to the DNS caching issue, Karel Zikmund writes,

We are actively discussing the design to address DNS changes problem directly in ManagedHandler. Currently we're considering 2 options: either DNS TTL support (#24257) or ConnectionLeaseTimeout-like API (#26331). We will make sure that the DNS changes scenario is addressed in combination with HttpClientFactory feature in 2.1 timeframe.

Message Handlers and Automatic Retries

A little-known feature of HttpClient is the ability to add message handlers. Out of the box, the HttpClientHandler controls features such as whether or not to allow auto-redirects, which cookie container to use, and how pre-authentication works.

This can be further extended by implementing a subclass of DelegatingHandler. In a demonstration on Channel 9, Daniel Roth shows how to create a simple retry handler.

The HttpClientFactory compliments this capability by allowing developers to include HttpClientHandlers as part of the HttpClient configuration. This is intentionally done in a way to be DI friendly.

SocketHttpHandler

The HttpClientHandler subsystem isn't just for modifying behavior; it can also completely alter the way a HttpClient communicates with the network. Microsoft is taking advantage of this by introduction the SocketHttpHandler. This is a "new from-the-ground-up managed HttpClientHandler" that eliminates the "platform dependencies on libcurl (for linux) and WinHTTP (for Windows)". The announcement continues,

You can opt-in to using the SocketHTTPHandler in one the following ways with Preview 1: Environment variable: COMPlus_UseManagedHttpClientHandler=true AppContext: System.Net.Http.UseManagedHttpClientHandler=true

You can also enable sockets mode for ASP.NET. Eventually this may become the default with the current native implementations being opt-in.