Initiating a single HttpClient instance using Autofac

One of the most common faults when using the HttpClient class, is using a new instance for every web service call you are performing.

using (var httpClient = new HttpClient())
{
  // do stuff
}

As stated on the official documentation page, HttpClient is intended to be instantiated once per application, rather than per-use. More information can be found in the remarks section.

Now, if you are using Autofac and you do not specify a scope when registering your services, it defaults to Instance per Dependency, or transient as it’s also called. This means that every time your service is resolved a new instance is returned. And that’s something we don’t really want when using HttpClient.

Luckily, Autofac has the concept of Named and Keyed services, which we can leverage to uniquely identify our HttpClient instance, and register it as a singleton, so a single instance is shared between all requests.

public class CustomModuleLoader : Module
{
  protected override void Load(ContainerBuilder builder)
  {
    base.Load(builder);

    // Register a named HttpClient instance as a singleton.
    builder.Register(_ => {
      var httpClient = new HttpClient
      {
        BaseAddress = new Uri("https://api.github.com");
      }

      httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
      httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Awesome-Octocat-App");

      return httpClient;
    })
    .Named<HttpClient>("GitHubHttpClient")
    .SingleInstance();

    // Register an instance of our GitHubClient, as transient.
    builder.RegisterInstance(ctx => {
      // Resolve the HttpClient singleton instance.
      var httpClient = ctx.ResolveNamed<HttpClient>("GitHubHttpClient");
      var gitHubClient = new GitHubClient(httpClient);

      return gitHubClient;
    })
    .As<IGitHubClient>();
  }
}
comments powered by Disqus