I'm looking into using IHttpClientFactory
for calling external APIs in my ASP.NET Core app. I've seen a few examples where the client factory is created in the constructor of the service's class. Then the methods of that class call the client factory to generate an instance of HttpClient
to make HTTP requests. Like the following sample code:
public class MyTransientService: IMyService
{
private readonly IHttpClientFactory _clientFactory;
public MyTransientService(
IHttpClientFactory clientFactory
)
{
_clientFactory = clientFactory;
}
public async Task<MyData> GetData()
{
//construct the request
var httpClient = _clientFactory.CreateClient();
var response = await client.SendAsync(request);
...
}
}
If the service is registered as transient in Startup.cs, wouldn't a new instance of HttpClientFactory
be generated each time that the service is called? A new HttpClientFactory
per request? So wouldn't the following be a more efficient way to use the factory?
public class MyTransientService: IMyService
{
private readonly HttpClient _client;
public MyTransientService(HttpClient client)
{
_client = client;
}
public async Task<MyData> GetData()
{
Uri uri = new Uri(StaticUtils.AddQueryString(url, props));
var response = await _client.SendAsync(request);
...
}
}
I would consider creating the HttpClient yourself bad practice, on self you have control of how many is created. If MyTransientService
is transient, you will end up creating a lot of socket connections (one for each instance/request) HttpClient
is created to be reused.
Take a look at Typed clients: https://learn.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient("hello", c =>
{
c.BaseAddress = new Uri("http://localhost:5000");
})
.AddTypedClient<MyTransientService>();
services.AddControllers();
}
public class MyTransientService: IMyService
{
private readonly HttpClient _client;
public MyTransientService(
HtpClient client
)
{
_client = client;
}
public async Task<MyData> GetData()
{
Uri uri = new Uri(StaticUtils.AddQueryString(url, props));
var response = await _client.SendAsync(request);
...
}
}