Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inject one HttpClient into multiple services

I am building a client of an API. My API is rather big, so I decided to split it into about 5 (private) sub-clients, each covering different part of API. 5 clients are not very comfortable to use, so I'd like to have them under 1 (public) ApiClient, which will act as a kind of facade above these 5 clients. The thing is that I probably should share one HttpClient between all these sub-clients. As far as I know, I can do something like that:

services.AddHttpClient<SubClient1>(c => c.BaseAddress = new System.Uri("https://myapi.com"));

With the above line, my SubClient1 will be injected into my public ApiClient with the proper HttpClient instance already set up with BaseAddress. Now, how do I register all 5 of my sub-clients (SubClient1, SubClient2, SubClient3, ...) so that each of them receives the same HttpClient? I think the code below will create 5 HttpClient instances:

services.AddHttpClient<SubClient1>(c => c.BaseAddress = new System.Uri("https://myapi.com"));
services.AddHttpClient<SubClient2>(c => c.BaseAddress = new System.Uri("https://myapi.com"));
services.AddHttpClient<SubClient3>(c => c.BaseAddress = new System.Uri("https://myapi.com"));
services.AddHttpClient<SubClient4>(c => c.BaseAddress = new System.Uri("https://myapi.com"));
services.AddHttpClient<SubClient5>(c => c.BaseAddress = new System.Uri("https://myapi.com"));

How could I resolve this?

like image 984
mnj Avatar asked Mar 31 '26 00:03

mnj


1 Answers

I don't disagree with @Athanasios Kataras answer. But I don't see the reason why you need to make it into a singleton.

Basically there are 3 ways to dependency inject an http client into a service; Directly, Typed, and Named. What @Athanasios did was directly. But in this scenario I believe a Named HttpClient is the way to go. But you could also just use a typed that gets injected into the subclients assuming the behavior of the client is the same across all subclients.

In startup.cs or program.cs (depending on .net 5.0 or .net 6.0)

public class Startup
{
    private IConfiguration Configuration { get; }
    private IHostEnvironment HostEnvironment { get; set; }

    public Startup(IConfiguration configuration, IHostEnvironment env)
    {
        Configuration = configuration;
        HostEnvironment = env;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        //Named client
        services.AddHttpClient("myapi", c =>
        {
            c.BaseAddress = new System.Uri("https://myapi.com");
        });

        //Typed client
        services.AddHttpClient<iMyApi, MyApi>(c => 
            c.BaseAddress = new System.Uri("https://myapi.com");
        });
    }
}

That adds the HttpClient to the HttpClientFactory, that you can now use in whatever project.

Subclient.cs

public class SubClient
{
    private readonly IHttpClientFactory httpFactory;
    private readonly HttpClient namedClient;
    private readonly iMyApi typedClient;
    private readonly static string clientName = "myapi";

    public SubClient(IHttpClientFactory httpClientFactory, iMyApi myApiClient)
    {
        this.namedClient = httpClientFactory.Create(clientName);
        this.typedClient = myApiClient;
    }
}

With the typed client it depends on you creating an implementation that implements the endpoints of your api. The advantage here is that you have a transient client that can be used in any of your services. And you free yourself from what I suspect would be a lot of duplicate code.

like image 184
Kent Kostelac Avatar answered Apr 02 '26 14:04

Kent Kostelac



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!