title: Best way to use HTTPClient in ASP.Net Core as a DI Singleton
body: <p>I am trying to figure out how to best use the HttpClient class in ASP.Net Core.</p>
  
  <p>According to the documentation and several articles, the class is best instantiated once for the lifetime of the application and shared for multiple requests. Unfortunately, I could not find an example of how to correctly do this in Core so I’ve come up with the following solution. </p>
  
  <p>My particular needs require the use of 2 different endpoints (I have an APIServer for business logic and an API driven ImageServer), so my thinking is to have 2 HttpClient singletons that I can use in the application.</p>
  
  <p>I’ve configured my servicepoints in the appsettings.json as follows:</p>
  
  <pre><code>"ServicePoints": {
  "APIServer": "http://localhost:5001",
  "ImageServer": "http://localhost:5002",
  }
  </code></pre>
  
  <p>Next, I created a HttpClientsFactory that will instantiate my 2 httpclients and hold them in a static Dictionary.</p>
  
  <pre><code>public class HttpClientsFactory : IHttpClientsFactory
  {
      public static Dictionary&lt;string, HttpClient&gt; HttpClients { get; set; }
      private readonly ILogger _logger;
      private readonly IOptions&lt;ServerOptions&gt; _serverOptionsAccessor;
  
      public HttpClientsFactory(ILoggerFactory loggerFactory, IOptions&lt;ServerOptions&gt; serverOptionsAccessor) {
          _logger = loggerFactory.CreateLogger&lt;HttpClientsFactory&gt;();
          _serverOptionsAccessor = serverOptionsAccessor;
          HttpClients = new Dictionary&lt;string, HttpClient&gt;();
          Initialize();
      }
  
      private void Initialize()
      {
          HttpClient client = new HttpClient();
          // ADD imageServer
          var imageServer = _serverOptionsAccessor.Value.ImageServer;
          client.BaseAddress = new Uri(imageServer);
          HttpClients.Add("imageServer", client);
  
          // ADD apiServer
          var apiServer = _serverOptionsAccessor.Value.APIServer;
          client.BaseAddress = new Uri(apiServer);
          HttpClients.Add("apiServer", client);
      }
  
      public Dictionary&lt;string, HttpClient&gt; Clients()
      {
          return HttpClients;
      }
  
      public HttpClient Client(string key)
      {
          return Clients()[key];
      }
    } 
  </code></pre>
  
  <p>Then, I created the interface that I can use when defining my DI later on. Notice that the HttpClientsFactory class inherits from this interface.</p>
  
  <pre><code>public interface IHttpClientsFactory
  {
      Dictionary&lt;string, HttpClient&gt; Clients();
      HttpClient Client(string key);
  }
  </code></pre>
  
  <p>Now I am ready to inject this into my Dependency container as follows in the Startup class under the ConfigureServices method.</p>
  
  <pre><code>// Add httpClient service
          services.AddSingleton&lt;IHttpClientsFactory, HttpClientsFactory&gt;();
  </code></pre>
  
  <p>All is now set-up to start using this in my controller.<br>
  Firstly, I take in the dependency. To do this I created a private class property to hold it,  then add it to the constructor signature and finish by assigning the incoming object to the local class property.</p>
  
  <pre><code>private IHttpClientsFactory _httpClientsFactory;
  public AppUsersAdminController(IHttpClientsFactory httpClientsFactory)
  {
     _httpClientsFactory = httpClientsFactory;
  }
  </code></pre>
  
  <p>Finally, we can now use the Factory to request a htppclient and execute a call. Below, an example where I request an image from the imageserver using the httpclientsfactory:</p>
  
  <pre><code>[HttpGet]
      public async Task&lt;ActionResult&gt; GetUserPicture(string imgName)
      {
          // get imageserver uri
          var imageServer = _optionsAccessor.Value.ImageServer;
  
          // create path to requested image
          var path = imageServer + "/imageuploads/" + imgName;
  
          var client = _httpClientsFactory.Client("imageServer");
          byte[] image = await client.GetByteArrayAsync(path);
  
          return base.File(image, "image/jpeg");
      }
  </code></pre>
  
  <p>Done!</p>
  
  <p>I’ve tested this and it work great on my development environment. However, I am not sure if this is the best way to implement this. I remain with the following questions:</p>
  
  <ol>
  <li>Is this solution thread safe? (according to the MS doc: ‘Any public static (Shared in Visual Basic) members of this type are thread safe.’)</li>
  <li>Will this set-up be able to handle a heavy load without opening many separate connection?</li>
  <li>What to do in ASP.Net core to handle the DNS problem described in ‘Singleton HttpClient? Beware of this serious behaviour and how to fix.’ located at  <a href="http://byterot.blogspot.be/2016/07/singleton-httpclient-dns.html" rel="noreferrer">http://byterot.blogspot.be/2016/07/singleton-httpclient-dns.html</a> </li>
  <li>Any other improvements or suggestions?</li>
  </ol>