According to examples provided by ASP.NET Core 2.2 documentation in MSDN, it is possible to inject HttpClient to a typed clients (service-classes) by adding the following line to Startup.cs:
// Startup.cs
services.AddHttpClient<GitHubService>();
From controller class it will look like (from now I will use GitHub as a simplification for a domain model):
// GitHubController.cs
public class GitHubController : Controller
{
private readonly GitHubService _service;
public GitHubController(GitHubService service)
{
_service = service;
}
}
However, I use MediatR library in my project, so my project structure looks a bit different. I have 2 projects - GitHubFun.Api, GitHubFun.Core - ASP.NET Core 2.2 API project and .NET Core 2.2 class library respectively.
My controller:
// GitHubController.cs
public class GitHubController : Controller
{
private readonly IMediator _mediator;
public GitHubController(IMediator mediator)
{
_mediator= mediator;
}
public async Task<IActionResult> GetGitHubRepositoryInfo(
GetGitHubRepositoryCommand command)
{
_mediator.Send(command);
}
}
And my handler class:
// GetGitHubRepositoryHandler.cs
public class GetGitHubRepositoryHandler :
IRequestHandler<GetGitHubRepositoryCommand , GetGitHubRepositoryCommandResult>
{
private HttpClient _httpClient;
public GetGitHubRepositoryHandler(HttpClient httpClient)
{
_httpClient = httpClient;
}
}
When I make HTTP request and call an API method, it successfully injects IMediator, but throws an exception on _mediator.Send(command) line.
Exception body:
System.InvalidOperationException: Error constructing handler for request of type MediatR.IRequestHandler`2[IDocs.CryptoServer.Core.Commands.ExtractX509Command,IDocs.CryptoServer.Core.Commands.ExtractX509CommandResult]. Register your handlers with the container. See the samples in GitHub for examples. ---> System.InvalidOperationException: Unable to resolve service for type 'System.Net.Http.HttpClient' while attempting to activate 'IDocs.CryptoServer.Core.Handlers.ExtractX509CommandHandler'
(ExtractX509CommandHandler - is just a real domain model, instead of GetGitHubRepositoryHandler).
It seems that ASP.NET Core DI cannot resolve DI and inject HttpClient to handler.
My Startup.cs has the following lines:
services.AddHttpClient<ExtractX509CommandHandler>();
services.AddMediatR(
typeof(Startup).Assembly,
typeof(ExtractX509CommandHandler).Assembly);
I found a solution. For some reasons, in this case we need to pass IHttpClientFactory from Microsoft.Extensions.Http.dll instead of HttpClient to handler class. I just changed one line, it was:
public GetGitHubRepositoryHandler(HttpClient httpClient)
and now:
public GetGitHubRepositoryHandler(IHttpClientFactory httpClientFactory)
and now it works as it should. I don't know why it works, so it will be perfect, if someone could explain what is the difference between injecting IHttpClientFactory and HttpClient to the class.
I found a solution.
I'm in ASP.NET Core 3.1.
My handler class :
public class GetProductsListQueryHandler : IRequestHandler<GetProductsListQueryModel, IEnumerable<Product>>
{
private readonly HttpClient _httpClient;
public GetProductsListQueryHandler(HttpClient httpClient)
{
_httpClient = httpClient;
}
You need to implement your HttpClient in your Startup like this :
services.AddHttpClient<IRequestHandler<GetProductsListQueryModel,IEnumerable<Product>>, GetProductsListQueryHandler>();
And it works! ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With