与 IMediatR 库一起使用时,无法在类型化客户端中注入 HttpClient

Isk*_*yev 6 c# mediatr asp.net-core-2.0

根据MSDN 中ASP.NET Core 2.2 文档提供的示例,可以通过将以下行添加到 Startup.cs 将 HttpClient 注入类型化客户端(服务类):

// Startup.cs
services.AddHttpClient<GitHubService>();
Run Code Online (Sandbox Code Playgroud)

从控制器类来看,它看起来像(从现在开始我将使用 GitHub 作为域模型的简化):

// GitHubController.cs
public class GitHubController : Controller
{
    private readonly GitHubService _service;
    public GitHubController(GitHubService service)
    {
        _service = service;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我在我的项目中使用了MediatR库,所以我的项目结构看起来有点不同。我有 2 个项目 - GitHubFun.Api、GitHubFun.Core - ASP.NET Core 2.2 API 项目和 .NET Core 2.2 类库。

我的控制器:

// 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的处理程序类:

// GetGitHubRepositoryHandler.cs
public class GetGitHubRepositoryHandler : 
    IRequestHandler<GetGitHubRepositoryCommand , GetGitHubRepositoryCommandResult>
{
    private HttpClient _httpClient;

    public GetGitHubRepositoryHandler(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }
}
Run Code Online (Sandbox Code Playgroud)

当我发出 HTTP 请求并调用 API 方法时,它成功注入了 IMediator,但在_mediator.Send(command)行上引发了异常。

异常体:

System.InvalidOperationException:为 MediatR.IRequestHandler`2[IDocs.CryptoServer.Core.Commands.ExtractX509Command,IDocs.CryptoServer.Core.Commands.ExtractX509CommandResult] 类型的请求构建处理程序时出错。向容器注册您的处理程序。有关示例,请参阅 GitHub 中的示例。---> System.InvalidOperationException:尝试激活“IDocs.CryptoServer.Core.Handlers.ExtractX509CommandHandler”时无法解析“System.Net.Http.HttpClient”类型的服务

(ExtractX509CommandHandler - 只是一个真正的域模型,而不是 GetGitHubRepositoryHandler)。

似乎 ASP.NET Core DI 无法解析 DI 并将 HttpClient 注入处理程序。

我的 Startup.cs 有以下几行:

services.AddHttpClient<ExtractX509CommandHandler>();
services.AddMediatR(
       typeof(Startup).Assembly, 
       typeof(ExtractX509CommandHandler).Assembly);
Run Code Online (Sandbox Code Playgroud)

Isk*_*yev 5

我找到了解决方案。由于某些原因,在这种情况下,我们需要将 IHttpClientFactory 从 Microsoft.Extensions.Http.dll 而不是 HttpClient 传递给处理程序类。我只是改变了一行,它是:

public GetGitHubRepositoryHandler(HttpClient httpClient)
Run Code Online (Sandbox Code Playgroud)

现在:

public GetGitHubRepositoryHandler(IHttpClientFactory httpClientFactory)
Run Code Online (Sandbox Code Playgroud)

现在它可以正常工作了。我不知道它为什么会起作用,所以如果有人能解释将 IHttpClientFactory 和 HttpClient 注入到类中有什么区别,那就太完美了。