Everywhere I can see three main approaches to create clients (basic, named, typed) in DI, but I have found nowhere if to inject IHttpClientFactory
or HttpClient
(both possible).
Q1: What is the difference between injecting IHttpClientFactory
or HttpClient
please?
Q2: And if IHttpClientFactory
is injected, should I use factory.CreateClient()
for each call?
It has a method CreateClient which returns the HttpClient Object. But in reality, HttpClient is just a wrapper, for HttpMessageHandler. HttpClientFactory manages the lifetime of HttpMessageHandelr, which is actually a HttpClientHandler who does the real work under the hood.
Not only that HttpClientFactory can create and manage new HttpClient instances but also, it works with underlying handlers. Basically, when creating new HttpClient instances, it doesn't recreate a new message handler but it takes one from a pool. Then, it uses that message handler to send the requests to the API.
Since RestSharp uses the HttpClient, we should consider similar issues regarding the RestClient instantiation.
Http NuGet package that includes the AddHttpClient extension method for IServiceCollection. This extension method registers the internal DefaultHttpClientFactory class to be used as a singleton for the interface IHttpClientFactory .
HttpClient
can only be injected inside Typed clientsIHttpClientFactory
HttpClientMessageHandler
is managed by the framework, so you are not worried about (incorrectly) disposing the HttpClients
.In order to directly inject HttpClient
, you need to register a specific Typed service that will receive the client:
services.AddHttpClient<GithubClient>(c => c.BaseAddress = new System.Uri("https://api.github.com"));
Now we can inject that inside the typed GithubClient
public class GithubClient { public GithubClient(HttpClient client) { // client.BaseAddress is "https://api.github.com" } }
You can't inject the HttpClient
inside AnotherClient
, because it is not typed to AnotherClient
public class AnotherClient { public AnotherClient(HttpClient client) { // InvalidOperationException, can't resolve HttpClient } }
You can, however:
1. Inject the IHttpClientFactory
and call CreateClient()
. This client will have BaseAddress
set to null
.
2. Or configure AnotherClient
as a different typed client with, for example, a different BaseAdress
.
Based on your comment, you are registering a Named client. It is still resolved from the IHttpClientFactory.CreateClient() method, but you need to pass the 'name' of the client
Registration
services.AddHttpClient("githubClient", c => c.BaseAddress = new System.Uri("https://api.github.com"));
Usage
// note that we inject IHttpClientFactory public HomeController(IHttpClientFactory factory) { this.defaultClient = factory.CreateClient(); // BaseAddress: null this.namedClient = factory.CreateClient("githubClient"); // BaseAddress: "https://api.github.com" }
Sadly I cannot comment, but only Post an answer. Therefore I suggest you should check out the following Links:
https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests
https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/
Regarding your Questions it more or Less boils down to this:
Q1 -> IHttpClientFactory handles the connection pools of HttpClient instances and this will help you regarding load and dispose problems as discribed in the links, if the HttpClient is used wrong.
Q2 -> yes you should use factory.create client according to microsoft docs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With