Reputation: 160
I'm working on an ASP.NET Core 5.0 project which has a service that accesses an API. Based on the code below, I'd expect the HttpClient supplied to ToornamentService's constructor to contain the declared BaseAddress and API key header.
However, when debugging, I noticed that the HttpClient never has either of those. BaseAdress is null, and the header is missing. I've tried using an IHttpClientFactory instead of the typed client, but I end up with the same result.
What am I doing wrong?
ConfigureServices Method:
public void ConfigureServices(IServiceCollection services)
{
//Omitted for brevity
services.AddHttpClient<ToornamentService>(c =>
{
c.BaseAddress = new Uri("https://api.toornament.com/");
c.DefaultRequestHeaders.Add("X-Api-Key", Configuration["Toornament:ApiKey"]);
});
services.AddTransient<ToornamentService>();
}
ToornamentService class:
public ToornamentService(HttpClient client)
{
Client = client; // client.BaseAddress here is null
}
Upvotes: 9
Views: 1742
Reputation: 407
Just expanding on @Andy's response, here's the official link for your use case AddHttpClient<TClient>(IServiceCollection, Action<HttpClient>)
The explanation is on their website
Type Parameters TClient The type of the typed client. They type specified will be registered in the service collection as a transient service. See ITypedHttpClientFactory<TClient> for more details about authoring typed clients.
So indeed, your service is automatically registered in DI as transient, so no need to reregister it again, since it'll override the DI chain.
I have struggled with that as well... this explanation is only on the website, the intellisense information does not contain this.
Upvotes: 0
Reputation: 13557
Remove this line: services.AddTransient<ToornamentService>();
When you call AddHttpClient
, it registers the service for you as transient.
So what you are doing is registering it twice. And since your transient registration is the last registration, that takes precedence over the AddHttpClient
registration.
Upvotes: 19