Reputation: 2800
I came to a point where I needed to replace usage of HttpClient with IHttpClientFactory in order to reduce number of sockets that are in use and avoid socket exhaustion.
As preferable approach, I wanted to use IHttpClientFactory and register it by using Autofac, and I also wanted to confirm the difference between usage of HttpClient and IHttpClientFactory - how to know if my implementation is working properly?
My base implementation of the class that uses IHttpClientFactory goes something like this (one of the classes):
public class ImportHttpClient : IImportHttpClientAccessor
{
public HttpClient Client { get; }
public ImportHttpClient(IHttpClientFactory httpClientFactory)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Client = httpClientFactory.CreateClient();
Client.BaseAddress = new Uri(GlobalVariables.ImportServiceSettings.BaseUrl);
}
}
and registration of this class with Autofac is very straightforward:
builder.RegisterType<ImportHttpClient>().As<IImportHttpClientAccessor>().InstancePerLifetimeScope();
But, the registration of IHttpClientFactory remained the problem and also a test to compare before/after using IHttpClientFactory.
Upvotes: 1
Views: 1435
Reputation: 48486
Rather than the accepted answer, you should use the Autofac.Extensions.DependencyInjection
NuGet package. Then use the builder.Populate(...)
method.
ContainerBuilder builder = /* Get it from wherever */;
var services = new ServiceCollection();
// Example registration of a typed HttpClient
services.AddHttpClient<IMyClient, MyClient>();
// Additional registrations using extension methods go here
builder.Populate(services);
This avoids re-registering your client into a fresh service collection each time, and building a new service provider. If you're resolving a dependency registered using Autofac, that wouldn't resolve in this service provider either.
See also https://autofac.readthedocs.io/en/latest/integration/netcore.html#quick-start for another example.
Upvotes: 1
Reputation: 2800
After a lot of research and checking out different resources, I managed to find a solution to my problems.
Registering IHttpClientFactory with Autofac in .NET 4.8 is done like this:
builder.Register(ctx =>
{
var services = new ServiceCollection();
services.AddHttpClient();
var provider = services.BuildServiceProvider();
return provider.GetRequiredService<IHttpClientFactory>();
});
For testing HttpClient vs IHttpClientFactory I used netstat, and these are the results: With HttpClient (no HttpClientFactory):
as you can see there is a lot of open connections that are not automatically closed for a while.
Now, the same process, but with using IHttpClientFactory:
As you can see, instead of many connections that just "hang there", I got only several where connection is closed.
Upvotes: 4