Following is the code I am using:
namespace MySite.Api
{
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using Syste
HttpClient
should be singleton-scoped. There's a finite number of connections available on your machine, and since HttpClient
holds on to connections it creates, having multiple instances floating around can quickly exhaust your connection pool.
Beginning with ASP.NET Core 2.1, there exists IHttpClientFactory
which provides a simple and reusable way of injecting properly scoped HttpClient
instances. However, since you're using 1.1, that's not available to you. The recommended path would be to upgrade your project to 2.1. The 1.X line of ASP.NET Core is frankly trash. It wasn't ready for production use, despite being an official release.
If you insist on sticking with 1.1, then you'll need to implement your own method of reusing HttpClient
instances. The most straightforward way is to use "accessor" classes, which you can then utilize to inject different HttpClient
s into different objects. For example:
public class ApiHttpClientAccessor : IDisposable
{
public ApiHttpClientAccessor()
{
HttpClient = new HttpClient
{
BaseAddress = new Uri("https://foo.com")
};
}
public HttpClient HttpClient { get; }
private bool _disposed;
public virtual void Dispose(bool disposing)
{
if (disposing && !_disposed)
{
HttpClient.Dispose();
}
_disposed = true;
}
public bool Dispose() =>
Dispose(true);
}
Then, you can register this accessor class as a singleton, meaning it will only be created once (so the contained HttpClient
will also only be created once). Then, set up your class to accept this accessor in its constructor:
public class ApiQuery : IApiQuery
{
private readonly HttpClient _client;
public ApiQuery(ApiHttpClientAccessor httpClientAccessor)
{
_client = (httpClientAccessor ?? throw new ArgumentNullException(nameof(httpClientAccessor))).HttpClient;
}
...
}
And in Startup.cs
:
services.AddSingleton<ApiHttpClientAccessor>();
services.AddTransient<IApiQuery, ApiQuery>();