与 IMediatR 库一起使用时无法在类型化客户端中注入 HttpClient
Cannot inject HttpClient in typed client while using with IMediatR library
根据 MSDN 中 ASP.NET Core 2.2 文档提供的示例,可以通过添加以下行将 HttpClient 注入类型化的客户端 (service-classes)到 Startup.cs:
// Startup.cs
services.AddHttpClient<GitHubService>();
从控制器 class 看起来像(从现在开始我将使用 GitHub 作为域模型的简化):
// GitHubController.cs
public class GitHubController : Controller
{
private readonly GitHubService _service;
public GitHubController(GitHubService service)
{
_service = service;
}
}
但是,我在我的项目中使用了 MediatR 库,所以我的项目结构看起来有点不同。我有 2 个项目 - GitHubFun.Api、GitHubFun.Core - ASP.NET Core 2.2 API 项目和 .NET Core 2.2 class图书馆分别。
我的控制器:
// 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);
}
}
还有我的经纪人class:
// GetGitHubRepositoryHandler.cs
public class GetGitHubRepositoryHandler :
IRequestHandler<GetGitHubRepositoryCommand , GetGitHubRepositoryCommandResult>
{
private HttpClient _httpClient;
public GetGitHubRepositoryHandler(HttpClient httpClient)
{
_httpClient = httpClient;
}
}
当我发出 HTTP 请求并调用 API 方法时,它成功注入了 IMediator,但在 _mediator.Send(command) 行抛出异常。
异常正文:
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 - 只是一个真正的域模型,而不是 GetGitHubRepositoryHandler)。
似乎ASP.NET核心DI无法解析DI并将HttpClient注入处理程序。
我的Startup.cs有以下几行:
services.AddHttpClient<ExtractX509CommandHandler>();
services.AddMediatR(
typeof(Startup).Assembly,
typeof(ExtractX509CommandHandler).Assembly);
我找到了解决办法。由于某些原因,在这种情况下,我们需要将 IHttpClientFactory 从 Microsoft.Extensions.Http.dll 而不是 HttpClient 传递给处理程序 class。我只更改了一行,它是:
public GetGitHubRepositoryHandler(HttpClient httpClient)
现在:
public GetGitHubRepositoryHandler(IHttpClientFactory httpClientFactory)
现在它可以正常工作了。我不知道它为什么会起作用,所以如果有人可以解释将 IHttpClientFactory 和 HttpClient 注入 class.
之间的区别,那将是完美的
我找到了解决办法。
我在 ASP.NET Core 3.1.
我的经纪人 class :
public class GetProductsListQueryHandler : IRequestHandler<GetProductsListQueryModel, IEnumerable<Product>>
{
private readonly HttpClient _httpClient;
public GetProductsListQueryHandler(HttpClient httpClient)
{
_httpClient = httpClient;
}
您需要像这样在 Startup 中实现 HttpClient :
services.AddHttpClient<IRequestHandler<GetProductsListQueryModel,IEnumerable<Product>>, GetProductsListQueryHandler>();
而且有效! ;)
根据 MSDN 中 ASP.NET Core 2.2 文档提供的示例,可以通过添加以下行将 HttpClient 注入类型化的客户端 (service-classes)到 Startup.cs:
// Startup.cs
services.AddHttpClient<GitHubService>();
从控制器 class 看起来像(从现在开始我将使用 GitHub 作为域模型的简化):
// GitHubController.cs
public class GitHubController : Controller
{
private readonly GitHubService _service;
public GitHubController(GitHubService service)
{
_service = service;
}
}
但是,我在我的项目中使用了 MediatR 库,所以我的项目结构看起来有点不同。我有 2 个项目 - GitHubFun.Api、GitHubFun.Core - ASP.NET Core 2.2 API 项目和 .NET Core 2.2 class图书馆分别。
我的控制器:
// 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);
}
}
还有我的经纪人class:
// GetGitHubRepositoryHandler.cs
public class GetGitHubRepositoryHandler :
IRequestHandler<GetGitHubRepositoryCommand , GetGitHubRepositoryCommandResult>
{
private HttpClient _httpClient;
public GetGitHubRepositoryHandler(HttpClient httpClient)
{
_httpClient = httpClient;
}
}
当我发出 HTTP 请求并调用 API 方法时,它成功注入了 IMediator,但在 _mediator.Send(command) 行抛出异常。
异常正文:
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 - 只是一个真正的域模型,而不是 GetGitHubRepositoryHandler)。
似乎ASP.NET核心DI无法解析DI并将HttpClient注入处理程序。
我的Startup.cs有以下几行:
services.AddHttpClient<ExtractX509CommandHandler>();
services.AddMediatR(
typeof(Startup).Assembly,
typeof(ExtractX509CommandHandler).Assembly);
我找到了解决办法。由于某些原因,在这种情况下,我们需要将 IHttpClientFactory 从 Microsoft.Extensions.Http.dll 而不是 HttpClient 传递给处理程序 class。我只更改了一行,它是:
public GetGitHubRepositoryHandler(HttpClient httpClient)
现在:
public GetGitHubRepositoryHandler(IHttpClientFactory httpClientFactory)
现在它可以正常工作了。我不知道它为什么会起作用,所以如果有人可以解释将 IHttpClientFactory 和 HttpClient 注入 class.
之间的区别,那将是完美的我找到了解决办法。
我在 ASP.NET Core 3.1.
我的经纪人 class :
public class GetProductsListQueryHandler : IRequestHandler<GetProductsListQueryModel, IEnumerable<Product>>
{
private readonly HttpClient _httpClient;
public GetProductsListQueryHandler(HttpClient httpClient)
{
_httpClient = httpClient;
}
您需要像这样在 Startup 中实现 HttpClient :
services.AddHttpClient<IRequestHandler<GetProductsListQueryModel,IEnumerable<Product>>, GetProductsListQueryHandler>();
而且有效! ;)