0

Considering these topics:

https://stackoverflow.com/a/22561368/648723

https://stackoverflow.com/a/67067195/648723

https://stackoverflow.com/a/35045301/648723

They said: keep an instance of HttpClient for the lifetime of your application

But when we create a new Blazor application, in Program.cs file, the default HttpClient registered as this:

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = "MyUrl"});
  1. Why Microsoft didn't use AddSingleton for HttpClient?

  2. Is it necessary to use IHttpClientFactory instead of HttpClient?

  3. If I want to use Multiple HttpClient in my Blazor application, How can I register and inject intended HttpClient (With intended base URL) in my code?

Thanks

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
Arian
  • 12,793
  • 66
  • 176
  • 300

2 Answers2

2

The topics you link say to create an instance of HttpClient per API you're connecting to which is an important difference. AddSingleton would only make sense if you're sure your application will only ever connect to one specific API.

You can instantiate an HttpClient just fine, but the factory pattern contains a lot of optimization on when to create a new instance or to reuse an existing instance. It also prevents you from running out of sockets which will happen if you have too many HttpClient instances at once. See here for more: https://www.stevejgordon.co.uk/introduction-to-httpclientfactory-aspnetcore

This post shows how to define multiple named HttpClients for different URLs: https://www.stevejgordon.co.uk/httpclientfactory-named-typed-clients-aspnetcore

Simmetric
  • 1,443
  • 2
  • 12
  • 20
  • _"`AddSingleton` would only make sense if you're sure your application will only ever connect to one specific API."_ only if base address is specified, OP can remove that. – Guru Stron Oct 18 '22 at 12:24
1

They said: keep an instance of HttpClient for the lifetime of your application

While it was a preferred approach for quite a long time but it has its drawbacks - for example handling DNS changes (though based on this comment it can be worked around by changing SocketsHttpHandler.PooledConnectionLifetime property to something else from the default InfiniteTimeSpan)

Why Microsoft didn't use AddSingleton for HttpClient?

I would argue this question should be addressed to Microsoft

Is it necessary to use IHttpClientFactory instead of HttpClient?

In theory - no, but it is recommended approach to handle the complexities of http calls and HttpClient lifetime, because most of them should be handled by the IHttpClientFactory and in general you will not need to care.

If I want to use Multiple HttpClient in my Blazor application, How can I register and inject intended HttpClient (With intended base URL) in my code?

It can be easily achieved with IHttpClientFactory by setting it up in the DI either with named clients or typed clients.

halfer
  • 19,824
  • 17
  • 99
  • 186
Guru Stron
  • 102,774
  • 10
  • 95
  • 132
  • 1
    Please be aware that [named](https://github.com/dotnet/runtime/blob/215b39abf947da7a40b0cb137eab4bceb24ad3e3/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientBuilderExtensions.cs#L47) and [typed](https://github.com/dotnet/runtime/blob/215b39abf947da7a40b0cb137eab4bceb24ad3e3/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientBuilderExtensions.cs#L274) clients are registered as `Transient`. – Peter Csala Oct 18 '22 at 12:31
  • @PeterCsala not quite - caching works at the *handler* level, not the HttpClient instance itself. HttpClientFactory will create new HttpClient instances as needed and initialize them with cached handlers. – Panagiotis Kanavos Oct 18 '22 at 12:35
  • @PanagiotisKanavos: I think Peter is right. Do you have reference for what you said? Thanks – Arian Oct 18 '22 at 15:17
  • I didn't say he's wrong - HttpClientFactory creates new instances than can be discarded. It's the *handlers* that are cached by default for 10 minutes then recycled. As for reference, I had to check the source back when HttpClientFactory was new and the docs .... a bit lacking, to find how to constrain connections to a bad external service – Panagiotis Kanavos Oct 18 '22 at 15:19
  • [Here's the code](https://github.com/dotnet/runtime/blob/57bfe474518ab5b7cfe6bf7424a79ce3af9d6657/src/libraries/Microsoft.Extensions.Http/src/DefaultHttpClientFactory.cs#L117). When a new HttpClient is needed, the factory creates a new instance with a handler coming from `_activeHandlers`. – Panagiotis Kanavos Oct 18 '22 at 15:32
  • Each cached handler entry has [an expiration timer](https://github.com/dotnet/runtime/blob/57bfe474518ab5b7cfe6bf7424a79ce3af9d6657/src/libraries/Microsoft.Extensions.Http/src/DefaultHttpClientFactory.cs#L232) that [removes the handler](https://github.com/dotnet/runtime/blob/57bfe474518ab5b7cfe6bf7424a79ce3af9d6657/src/libraries/Microsoft.Extensions.Http/src/DefaultHttpClientFactory.cs#L207) from `_activeHandlers` – Panagiotis Kanavos Oct 18 '22 at 15:32
  • The reason I had to check this was I was calling a badly written service with an equally bad sticky load balancer. When the service failed, the balancer would keep sending my requests to the same failed instance. – Panagiotis Kanavos Oct 18 '22 at 15:34