19

I know I'll get crucified for asking this question that has been asked a million times before and I promise you that I've looked at most of those questions/answers but I'm still a bit stuck.

This is a .NET Standard 2.0 class library supporting an ASP.NET Core 6 API.

In my Program.cs I create a named HttpClient like this:

builder.Services.AddHttpClient("XYZ_Api_Client", config =>
{
    var url = "https://example.com/api";
    config.BaseAddress = new Uri(url);
});

I have a custom client that will use this HttpClient and I create a singleton MyCustomClient in Program.cs so that my repositories can use it. The code is below. This is where I'm stuck as I'm not sure how to pass my named HttpClient into MyCustomClient.

builder.Services.AddSingleton(new MyCustomClient(???)); // I think I need to pass the HttpClient to my CustomClient here but not sure how

And my CustomClient needs to use this HttpClient named XYZ_Api_Client to do its job:

public class MyCustomClient
{
   private readonly HttpClient _client;
   public MyCustomClient(HttpClient client)
   {
       _client = client;
   }

   public async Task<bool> DoSomething()
   {
      var result = await _client.GetAsync();
      return result;
   }
}

So I'm not sure how I can pass this named HttpClient into MyCustomClient in the Program.cs.

1 Answer 1

42

You can directly inject the IHttpClientFactory in you class, and then assign the named HttpClient to a property.

Register the factory and your custom client:

builder.Services.AddHttpClient("XYZ_Api_Client", config =>
{
    var url = "https://example.com/api";
    config.BaseAddress = new Uri(url);
});

// no need to pass anything, the previous line registers the IHttpClientFactory in the container
builder.Services.AddSingleton<MyCustomClient>();

And then in you class:

public class MyCustomClient
{
   private readonly HttpClient _client;
   public MyCustomClient(IHttpClientFactory factory)
   {
       _client = factory.CreateClient("XYZ_Api_Client");
   }
   // ...
}

Or, you can pass the named instance when registering MyCustomClient

Register the factory and your custom client:

builder.Services.AddHttpClient("XYZ_Api_Client", config =>
{
    var url = "https://example.com/api";
    config.BaseAddress = new Uri(url);
});

// specify the factory for your class 
builder.Services.AddSingleton<MyCustomClient>(sp => 
{
    var factory = sp.GetService<IHttpClientFactory>();
    var httpClient = factory.CreateClient("XYZ_Api_Client");
    
    return new MyCustomClient(httpClient);
});

And then in you class:

public class MyCustomClient
{
   private readonly HttpClient _client;
   public MyCustomClient(HttpClient client)
   {
       _client = client;
   }
   // ...
}

You can also do this:

// register the named client with the name of the class
builder.Services.AddHttpClient("MyCustomClient", config =>
{
    config.BaseAddress = new Uri("https://example.com/api");
});

// no need to specify the name of the client
builder.Services.AddHttpClient<MyCustomClient>();

What AddHttpClient<TClient>(IServiceCollection) does is

Adds the IHttpClientFactory and related services to the IServiceCollection and configures a binding between the TClient type and a named HttpClient. The client name will be set to the full name of TClient.

You can find the full documentation here.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you Alexandra for the super nice and detailed explanations!

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.