I've read that HttpMessageHandlers
are recycled every 2 minutes, but I'm not sure if a new one is assigned to an existing HttpClient
?
I've tested it out by using SetHandlerLifetime(TimeSpan.FromSeconds(5));
and even after 2 minutes with countless requests, the httpClient is continuing to work, which is a good sign?
Does that mean that I have no cause for concern with DNS changes/socket exhaustion?
Inside ConfigureServices method:
var myOptions = app.ApplicationServices.GetService<IOptionsMonitor<MyOptions>>();
HttpClient httpClient = app.ApplicationServices.GetService<IHttpClientFactory>().CreateClient();
MyStaticObject.Configure(myOptions, httpClient);
EDIT: Added some sample code.
There are a few things to look at here, with the first being does MyStaticObject
actually need to be static? If it does, I would recommend instead registering it as a Singleton so that you can still leverage dependency injection. Once you have done that, you can register IHttpClientFactory
and use it from your code. Your ConfigureServices
method may end up looking something like this
public void ConfigureServices(IServiceCollection services)
{
//The base extension method registers IHttpClientFactory
services.AddHttpClient();
services.AddSingleton<IMySingletonObject, MySingletonObject>();
}
Then in your consuming class, MySingletonObject
in this case, you would configure it as such
public class MySingletonObject
{
private readonly IHttpClientFactory _clientFactory;
public MySingletonObject(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
public async Task SomeMethodThatUsesTheClient()
{
var client = _clientFactory.CreateClient();
//use the client
}
}
The reason for this is that IHttpClientFactory
handles the lifetime and pool concerns for us. Per the docs:
Manages the pooling and lifetime of underlying HttpClientMessageHandler instances. Automatic management avoids common DNS (Domain Name System) problems that occur when manually managing HttpClient lifetimes.
This happens when you make the CreateClient
call, so you want to do this inside the code using the client, as opposed to on startup of your application.
As a side note, if you do not need this class to be a singleton at all, you can use the extenion services.AddHttpClient<IMyClass, MyClass>()
and inject an HttpClient
directly into the class. The DI container will handle getting a client from the factory behind the scenes for you.