C#
Dependency Injection
.NET Core
HttpClient
IServiceCollection

IServiceCollection does not contain a defintion for AddHttpClient

Object-Oriented Design practice on Codemia

Turn requirements into classes, and defend the design, on the problems that come up in OOD rounds.

Practice OOD

Introduction

When the compiler reports that IServiceCollection does not contain a definition for AddHttpClient, the fix is almost always one of two things: add using Microsoft.Extensions.DependencyInjection; to the source file, or add a reference to the Microsoft.Extensions.Http NuGet package in the project that contains the call. AddHttpClient is an extension method, so the compiler can only discover it when both the namespace import and the assembly reference are present.

Why This Error Is Misleading

Extension methods in C# look like regular instance methods when you call them, but the compiler resolves them differently. An extension method is a static method in a static class, discoverable only when the namespace containing that class is imported via a using directive.

AddHttpClient is defined in the Microsoft.Extensions.DependencyInjection.HttpClientFactoryServiceCollectionExtensions class, which lives in the Microsoft.Extensions.Http assembly. When the compiler cannot find this extension, it reports the error as if IServiceCollection itself is missing the method, which obscures the real cause.

 
error CS1061: 'IServiceCollection' does not contain a definition for 'AddHttpClient'
and no accessible extension method 'AddHttpClient' accepting a first argument of type
'IServiceCollection' could be found

The second half of this error message hints at the actual problem: "no accessible extension method could be found."

Fix 1: Add the Using Directive

The most common fix. The source file that calls AddHttpClient must import the namespace:

csharp
using Microsoft.Extensions.DependencyInjection;

This single line resolves the error in the majority of cases because ASP.NET Core web projects typically already reference the Microsoft.Extensions.Http assembly through the shared framework.

Before

csharp
1// Missing using directive
2var builder = WebApplication.CreateBuilder(args);
3builder.Services.AddHttpClient("github", client =>
4{
5    client.BaseAddress = new Uri("https://api.github.com/");
6});
7// Compiler error: CS1061

After

csharp
1using Microsoft.Extensions.DependencyInjection;
2
3var builder = WebApplication.CreateBuilder(args);
4builder.Services.AddHttpClient("github", client =>
5{
6    client.BaseAddress = new Uri("https://api.github.com/");
7});
8// Compiles successfully

Fix 2: Add the NuGet Package Reference

If adding the using directive does not resolve the error, the project is missing a reference to the assembly that contains the extension method.

For .NET CLI

bash
dotnet add package Microsoft.Extensions.Http

For the .csproj file

xml
1<Project Sdk="Microsoft.NET.Sdk">
2  <PropertyGroup>
3    <TargetFramework>net8.0</TargetFramework>
4  </PropertyGroup>
5
6  <ItemGroup>
7    <PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
8  </ItemGroup>
9</Project>

For Package Manager Console (Visual Studio)

powershell
Install-Package Microsoft.Extensions.Http

After adding the package, restore dependencies and rebuild:

bash
dotnet restore
dotnet build

When Each Fix Applies

Project TypeNamespace Import Needed?Package Reference Needed?
ASP.NET Core Web AppYesNo (included via shared framework)
ASP.NET Core Web APIYesNo (included via shared framework)
Class Library targeting .NET 8+YesYes
Console ApplicationYesYes
Worker ServiceYesUsually no (included in template)
Blazor ServerYesNo (included via shared framework)
xUnit / NUnit Test ProjectYesYes

ASP.NET Core web projects reference the Microsoft.AspNetCore.App shared framework, which includes Microsoft.Extensions.Http. Class libraries, console apps, and test projects do not, so they need an explicit package reference.

The Multi-Project Trap

This is the scenario that catches experienced developers. Consider a solution with this structure:

 
1MySolution/
2  MyApi/           (ASP.NET Core Web API)
3    Program.cs
4    MyApi.csproj   (references Microsoft.AspNetCore.App)
5  MyApi.Core/      (Class Library)
6    ServiceRegistration.cs
7    MyApi.Core.csproj   (does NOT reference Microsoft.Extensions.Http)

If ServiceRegistration.cs in the class library calls AddHttpClient, the build fails even though the web project has the shared framework reference. Compilation happens at the project level. The class library needs its own reference:

xml
1<!-- MyApi.Core.csproj -->
2<Project Sdk="Microsoft.NET.Sdk">
3  <PropertyGroup>
4    <TargetFramework>net8.0</TargetFramework>
5  </PropertyGroup>
6
7  <ItemGroup>
8    <PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
9  </ItemGroup>
10</Project>

This is the most common cause of the error in real-world codebases with clean architecture or layered project structures.

Verifying the Fix

A minimal program that compiles confirms the extension method is available:

csharp
1using System;
2using Microsoft.Extensions.DependencyInjection;
3
4var services = new ServiceCollection();
5
6services.AddHttpClient("example", client =>
7{
8    client.BaseAddress = new Uri("https://api.example.com/");
9    client.DefaultRequestHeaders.Add("Accept", "application/json");
10    client.Timeout = TimeSpan.FromSeconds(30);
11});
12
13Console.WriteLine("HttpClient registered successfully.");

If this compiles, the issue in your application is project-specific, not environmental.

Named vs Typed Clients

Once the error is resolved, you have two main patterns for registering HTTP clients.

Named Clients

Named clients are identified by a string key:

csharp
1services.AddHttpClient("payments", client =>
2{
3    client.BaseAddress = new Uri("https://payments.example.com/");
4});
5
6services.AddHttpClient("inventory", client =>
7{
8    client.BaseAddress = new Uri("https://inventory.example.com/");
9});

Consumers request a specific client by name through IHttpClientFactory:

csharp
1public class OrderService
2{
3    private readonly IHttpClientFactory _factory;
4
5    public OrderService(IHttpClientFactory factory) => _factory = factory;
6
7    public async Task ProcessOrderAsync()
8    {
9        using var client = _factory.CreateClient("payments");
10        var response = await client.GetAsync("status");
11    }
12}

Typed Clients

Typed clients bind configuration to a specific class:

csharp
1public class PaymentsClient
2{
3    private readonly HttpClient _http;
4
5    public PaymentsClient(HttpClient http)
6    {
7        _http = http;
8    }
9
10    public async Task<string> GetStatusAsync(CancellationToken ct)
11    {
12        return await _http.GetStringAsync("status", ct);
13    }
14}
15
16// Registration
17services.AddHttpClient<PaymentsClient>(client =>
18{
19    client.BaseAddress = new Uri("https://payments.example.com/");
20});

Typed clients are injected directly, without needing IHttpClientFactory:

csharp
1public class OrderService
2{
3    private readonly PaymentsClient _payments;
4
5    public OrderService(PaymentsClient payments) => _payments = payments;
6}

Comparison

FeatureNamed ClientsTyped Clients
RegistrationString keyClass type
InjectionVia IHttpClientFactoryDirect injection
Compile-time safetyNo (string key)Yes (type checked)
Configuration co-locationSeparate from usageNext to the client class
Best forMany simple endpointsDedicated service clients

Adding Delegating Handlers

A common follow-up after registering HTTP clients is adding cross-cutting concerns like logging, retry, or authentication:

csharp
1services.AddHttpClient<PaymentsClient>(client =>
2{
3    client.BaseAddress = new Uri("https://payments.example.com/");
4})
5.AddHttpMessageHandler<AuthTokenHandler>()
6.SetHandlerLifetime(TimeSpan.FromMinutes(5));

These methods are also extension methods from the same Microsoft.Extensions.Http package, so they become available once the package reference and namespace import are in place.

Common Pitfalls

  • Missing using Microsoft.Extensions.DependencyInjection; in the source file. This is the single most common cause. The package may be installed, but without the namespace import the compiler cannot discover the extension method.
  • Adding the package to the wrong project in a multi-project solution. The package reference must exist in the .csproj of the project that contains the AddHttpClient call, not just in the startup project.
  • Confusing the shared framework with explicit packages. ASP.NET Core web projects include Microsoft.Extensions.Http through the shared framework. Class libraries and console apps do not.
  • Version mismatches across projects. If one project references Microsoft.Extensions.Http 8.0.0 and another references 6.0.0, binding redirects or runtime errors can occur. Align versions across the solution.
  • Forgetting to restore packages after adding the reference. The package is not usable until dotnet restore runs. Most IDEs do this automatically, but CI pipelines may not.
  • Using new HttpClient() directly instead of IHttpClientFactory. This bypasses handler lifetime management and can lead to socket exhaustion under load. If you are fixing this error, commit to using the factory pattern properly.

Summary

  • AddHttpClient is an extension method defined in Microsoft.Extensions.Http, not a built-in member of IServiceCollection.
  • Add using Microsoft.Extensions.DependencyInjection; to the source file as the first fix.
  • Add a PackageReference to Microsoft.Extensions.Http if the project is a class library, console app, or test project.
  • In multi-project solutions, the package reference must exist in the project that contains the AddHttpClient call.
  • ASP.NET Core web projects inherit the package through the shared framework and typically only need the using directive.
  • Once the error is resolved, choose between named clients (string-keyed) and typed clients (class-based) depending on your architecture.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Object-Oriented Design practice on Codemia

Turn requirements into classes, and defend the design, on the problems that come up in OOD rounds.

Practice OOD

All Rights Reserved.