Reusing HttpClient with Dependency Injection

Full source code available here.

If you are using HttpClient to make requests for you, you might have come across some articles discussing how to reuse HttpClient. They strongly advocate for using a single HttpClient for as many requests as possible, i.e. not creating a new HttpClient for every request.
Not having to create/dispose of the HttpClient for every request should improve the performance of you application. One estimate states that every time you instantiate a HttpClient takes 35ms.

In this article I will show you how to use dependency injection to reuse the HttpClient in .Net Core, but the same principle applies in Framework 4.x applications.

The one advantage of creating a new HttpClient for every request is that you don’t need to worry about the DNS record of an endpoint changing during the lifetime of the application, this is common if you are swapping staging and production instances during a deployment. But this is easyly(ish) handled by the ServicePointManger.

Adding HttpClient to the DI Container
In Startup.cs add the below lines.

public void ConfigureServices(IServiceCollection services)
    Uri endPointA = new Uri("http://localhost:58919/"); // this is the endpoint HttpClient will hit
    HttpClient httpClient = new HttpClient()
        BaseAddress = endPointA,

    ServicePointManager.FindServicePoint(endPointA).ConnectionLeaseTimeout = 60000; // sixty seconds

    services.AddSingleton<HttpClient>(httpClient); // note the singleton

This approach is ideal if you have a limited number of endpoints and you know them at application startup. If you don’t know then endpoints at startup you can add the call to ServicePointManager where you HttpClient requests occur.

Using the HttpClient
Now I have the HttpClient registered with the Dependency Injection container, let’s take a look at the controller that uses it to make a request. See the inline comments.

public class ValuesController : Controller
    private readonly HttpClient _httpClient; // declare a HttpClient

    public ValuesController(HttpClient httpClient) // this is the singelton instance of HttpClient
        _httpClient = httpClient; // assign it to the local HttpClient

    // GET api/values
    public async Task<IActionResult> Get()
        string requestEndpoint = "api/products";

        HttpResponseMessage httpResponse = await _httpClient.GetAsync(requestEndpoint); // make request
        List<Product> products = await httpResponse.Content.ReasAsJsonAsync<List<Product>>();
        return Ok(products);

Full source code available here.

HttpContent ReadAsAsync with .NET Core 2

Full source code available here.

If you are used to using HttpContent.ReadAsAsync you might be surprised to learn that it is missing from .NET Core 2. You can try adding Microsoft.AspNet.WebApi.Client but you might get warnings or errors.

At some point Microsoft will come out with an updated NuGet package, but in the meantime here is a workaround.

At this extension method to your code.

using Newtonsoft.Json;
using System.Net.Http;
using System.Threading.Tasks;

namespace ReadAsAsyncCore
    public static class HttpContentExtensions
        public static async Task<T> ReadAsJsonAsync<T>(this HttpContent content)
            string json = await content.ReadAsStringAsync();
            T value = JsonConvert.DeserializeObject<T>(json);
            return value;

And use like this.

HttpResponseMessage httpResponse = await httpClient.GetAsync(requestEndpoint);
List<Product> products = await httpResponse.Content.ReadAsJsonAsync<List<Product>>();

Full source code available here.