I'm a bit confused about how to use a named HttpClient
which is registered as scoped
in a service that is registered as a singleton
. I've seen similar questions but I'm still not very clear about the usage.
Here's my service that needs to use the named HttpClient
to make API calls to my backend:
public class MyApiService : IMyApiService
{
private readonly HttpClient _myApiHttpClient;
public MyApiService(HttpClient myApiHttpClient)
{
_myApiHttpClient = myApiHttpClient;
}
public async Task<List<Customer>> GetCustomers()
{
var response = await _myApiHttpClient.GetAsync("/customers");
if(!response.IsSuccessStatusCode)
throw new Exception("API call failed!");
var json = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<List<Customer>>(json);
}
}
And in the Program.cs
, I register them as follows:
...
// Add HttpClient for API calls
builder.Services.AddHttpClient("MyApi",
client => client.BaseAddress = new Uri("https://api.test.com"))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
.CreateClient("MyApi"));
// Register services
builder.Services.AddSingleton<IMyApiService, MyApiService>();
await builder.Build().RunAsync();
This approach is throwing the following error:
Cannot consume scoped service 'System.Net.Http.HttpClient' from singleton 'MyBlazorWasmApp.Services.IMyApiService'
I understand why I get the error message. I haven't yet been able to figure out how to use the HttpClient
I define for calling my API in my singleton
services.
P.S. A quick and dirty approach would be to define my services as scoped
as in a Blazor WASM app, there would be no difference between registering them as singleton
or scoped
but I want to understand how to handle this scenario.
You can't, but you don't need to.
Use the IHttpClientFactory
to obtain short lived HttpClient
instances in a similar fashion to IDbContextFactory
. It's a much safer strategy in the async world of Blazor.
Your service injects the IHttpClientFactory
, and GetCustomers
gets a HttpClient
, scoped to the lifetime of GetCustomers
, to make the API call.
Read more here: https://learn.microsoft.com/en-us/dotnet/core/extensions/httpclient-factory