Skip to content

HCR088

A typed client registered via AddHttpClient<T> must have a constructor that accepts HttpClient.

Why

AddHttpClient<T> registers T with a factory that creates the configured HttpClient and passes it to the typed client's constructor. When T has no constructor parameter of type HttpClient, the runtime factory cannot inject the client — the registration silently resolves a typed client that never receives the configured HttpClient, or fails at resolution time depending on the DI container.

Bad

public sealed class GitHubClient
{
    public GitHubClient(IConfiguration configuration) { }
}

services.AddHttpClient<GitHubClient>();

Better

Accept the HttpClient the factory provides:

public sealed class GitHubClient
{
    private readonly HttpClient _httpClient;

    public GitHubClient(HttpClient httpClient, IConfiguration configuration)
    {
        _httpClient = httpClient;
    }
}

Current Detection

The implementation reports AddHttpClient<T> and AddHttpClient<TClient, TImplementation> invocations on Microsoft.Extensions.DependencyInjection receivers when the constructed type has no instance constructor with an HttpClient parameter. Invocations that pass a factory or configure lambda are skipped — the lambda supplies the instance itself. Abstract types, interfaces, unresolved type arguments, and non-framework AddHttpClient lookalikes are skipped.

Suppression

Suppress only when the typed client intentionally obtains its HttpClient through another mechanism (for example, an IHttpClientFactory parameter it calls itself). Prefer adding the HttpClient parameter — that is the pattern the registration API is built around.

References