One of the ways that you can inject an HttpClient instance in your ASP.NET Core application is through ‘Typed clients’. It is my preferred way as it takes maximal benefit from dependency injection, avoid the magic strings that ‘Named clients’ need and allows you to encapsulate the client configuration in one place.
A typical example of a named client is this:
public class TypedClientModel : PageModel | |
{ | |
private readonly GitHubService _gitHubService; | |
public TypedClientModel(GitHubService gitHubService) => | |
_gitHubService = gitHubService; | |
public IEnumerable<GitHubBranch>? GitHubBranches { get; set; } | |
public async Task OnGet() | |
{ | |
try | |
{ | |
GitHubBranches = await _gitHubService.GetAspNetCoreDocsBranchesAsync(); | |
} | |
catch (HttpRequestException) | |
{ | |
// ... | |
} | |
} | |
} |
This is possible thanks to following registration:
services.AddHttpClient<GitHubService>(httpClient => | |
{ | |
httpClient.BaseAddress = new Uri("https://api.github.com/"); | |
// ... | |
}); |
Most examples of the typed client you find out there are using a concrete class(like in the example above) but I wanted to use an interface.
Here was my first (naive) attempt:
// Notice the interface here 👇 | |
services.AddHttpClient<IGitHubService>(httpClient => | |
{ | |
httpClient.BaseAddress = new Uri("https://api.github.com/"); | |
// ... | |
}); | |
// 👇 This doesn't work | |
services.AddTransient<IGitHubService,GitHubService>(); |
The result of the code above was that an HttpClient instance was injected but it wasn’t using the configuration values I specified in the Startup.cs.
A second attempt was to specify the named client on the interface but this caused the same problem.
// Notice the concrete class here 👇 | |
services.AddHttpClient<GitHubService>(httpClient => | |
{ | |
httpClient.BaseAddress = new Uri("https://api.github.com/"); | |
// ... | |
}); | |
// 👇 This doesn't work | |
services.AddTransient<IGitHubService,GitHubService>(); |
The correct solution is the following:
// You should specify the interface here 👇 | |
services.AddHttpClient<IGitHubService, GitHubService>(httpClient => | |
{ | |
httpClient.BaseAddress = new Uri("https://api.github.com/"); | |
// ... | |
}); |