1

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);
        ...
    }
}

1 Answer 1

1

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);
        ...
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Good point, but I was not thinking to create the HttpClient myself. I thought that calling services.AddHttpClient() in ConfigureServices registers IHttpClientFactory. So I don't need to necessarily create a typed client. I will have more than one service that need HttpClient, so I don't want to create a typed HttpClient for each one.
Take a look at this: hanselman.com/blog/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.