HttpClient Singleton Implementation in ASP.NET MVC
<p>After reading this <a href="http://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/" rel="nofollow">blog post</a> and thisofficial note on <a href="https://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-net-client" rel="nofollow">www.asp.net</a>:</p>

<blockquote>
  <p>HttpClient is intended to be instantiated once and re-used throughout
  the life of an application. Especially in server applications,
  creating a new HttpClient instance for every request will exhaust the
  number of sockets available under heavy loads. This will result in
  SocketException errors.</p>
</blockquote>

<p>I discovered that our code was disposing the HttpClient on each call. I'm updating our code so that we reuse the HttClient, but I'm concerned our implement but not thread-safe.</p>

<p>Here is the current draft of new code:</p>

<p>For Unit Testing, we implemented an wrapper for HttpClient, the consumers call the wrapper:</p>

<pre><code> public class HttpClientWrapper : IHttpClient
    {
        private readonly HttpClient _client;

        public Uri BaseAddress
        {
            get
            {
                return _client.BaseAddress;
            }

            set
            {
                _client.BaseAddress = value;
            }
        }

        public HttpRequestHeaders DefaultRequestHeaders
        {
            get
            {
                return _client.DefaultRequestHeaders;
            }
        }

        public HttpClientWrapper()
        {
            _client = new HttpClient();
        }

        public Task&lt;HttpResponseMessage&gt; SendAsync(HttpRequestMessage request, String userOrProcessName)
        {
            IUnityContainer container = UnityCommon.GetContainer();
            ILogService logService = container.Resolve&lt;ILogService&gt;();

            logService.Log(ApplicationLogTypes.Debug, JsonConvert.SerializeObject(request), userOrProcessName);

            return _client.SendAsync(request);
        }

        #region IDisposable Support
        private bool disposedValue = false; // To detect redundant calls

        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing &amp;&amp; _client != null)
                {
                    _client.Dispose();
                }

                disposedValue = true;
            }
        }

        public void Dispose()
        {
            Dispose(true);
        }
        #endregion
    } 
</code></pre>

<p>Here is a service that calls:</p>

<pre><code>public class EnterpriseApiService : IEnterpriseApiService
    {
        private static IHttpClient _client;

        static EnterpriseApiService()
        {
            IUnityContainer container = UnityCommon.GetContainer();
            IApplicationSettingService appSettingService = container.Resolve&lt;IApplicationSettingService&gt;();

            _client = container.Resolve&lt;IHttpClient&gt;();
        }

        public EnterpriseApiService() { }

        public Task&lt;HttpResponseMessage&gt; CallApiAsync(Uri uri, HttpMethod method, HttpContent content, HttpRequestHeaders requestHeaders, bool addJsonMimeAccept = true)
        {
            IUnityContainer container = UnityCommon.GetContainer();
            HttpRequestMessage request;

           _client.BaseAddress = new Uri(uri.GetLeftPart(UriPartial.Authority));

            if (addJsonMimeAccept)
                _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            request = new HttpRequestMessage(method, uri.AbsoluteUri);

            // Removed logic that built request with content, requestHeaders and method

            return _client.SendAsync(request, UserOrProcessName);
        }
    }
</code></pre>

<p>My questions:</p>

<ol>
<li>Is this an appropriate approach to reuse the HttpClient object?</li>
<li>Is the static _httpClient field (populated with the static constructor) shared for all instances of EnterpriseApiService? I wanted to confirm since is being called by instance methods. </li>
<li>When CallApiAsync() is called, when that makes changes to the static HttpClient, such as the "_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"))" could those values be overwriten by another process before the last line "_client.SendAsync" is called? I'm concerned that halfway through processing CallApiAsync() the static instance is updated.</li>
<li>Since it is calling SendAsync(), are we guaranteed the response is mapped back to the correct caller? I want to confirm the response doesn't go to another caller. </li>
</ol>

<p><strong>Update:</strong>
Since I've removed the USING statements, and the Garage Collection doesn't call Dispose, I'm going to go with the safer approach of creating a new instance within the method. To reuse an instance of HttpClient even within the thread lifetime, it would require a significant reworking of the logic because the method sets HttpClient properties per call. </p>