Google "typed httpclient transient" is your friend: https://www.stevejgordon.co.uk/ihttpclientfactory-patterns-using-typed-clients-from-singleton-services
To put it simply, instead of injecting and using the typed HttpClient directly, you create a factory that depends on IServiceProvider, with a method that uses that service provider to return an instance of the typed HttpClient, and inject that factory. You then invoke the factory's creation method every time you need an instance of the typed HttpClient. The service provider does all the management of scope for you.
In other words, instead of the following:
services.AddHttpClient<IMyHttpClient, MyHttpClient>();
services.AddScoped<IDependsOnHttpClient, DependsOnHttpClient>();
...
public class DependsOnHttpClient : IDependsOnHttpClient
{
private readonly IMyHttpClient _httpClient;
public DependsOnHttpClient(IMyHttpClient httpClient)
=> _httpClient = httpClient;
public async Task DoSomethingWithHttpClientAsync()
=> _httpClient.GetAsync("https://foo.bar");
}
you write:
services.AddHttpClient<IMyHttpClient, MyHttpClient>();
services.AddSingleton<IMyHttpClientFactory, MyHttpClientFactory>();
services.AddSingleton<IDependsOnHttpClient, DependsOnHttpClient>();
...
public class MyHttpClientFactory : IMyHttpClientFactory
{
private readonly IServiceProvider _serviceProvider;
public MyHttpClientFactory(IServiceProvider serviceProvider)
=> _serviceProvider = serviceProvider;
public IMyHttpClient CreateClient()
=> _serviceProvider.GetRequiredService<IMyHttpClient>();
}
public class DependsOnHttpClient : IDependsOnHttpClient
{
private readonly IMyHttpClientFactory _httpClientFactory;
public DependsOnHttpClient(IMyHttpClientFactory httpClientFactory)
=> _httpClientFactory = httpClientFactory;
public async Task DoSomethingWithHttpClientAsync()
{
var httpClient = _httpClientFactory.CreateClient();
return await _httpClient.GetAsync("https://foo.bar");
}
}
At this point you might be wondering "what do I gain by writing all this code versus just injecting an IHttpClientFactory and calling its methods", and I'm honestly not sure of the answer. Perhaps with Roslyn source generators, we will be able to generate typed HttpClients and the factories for them.