C# 如何在类型化HttpClient示例中实现IHttpFactoryClient?

C# 如何在类型化HttpClient示例中实现IHttpFactoryClient?,c#,.net,rest,httpclient,httpclientfactory,C#,.net,Rest,Httpclient,Httpclientfactory,在我看到的每一个例子中,包括微软的和,作者都解释了IHttpClientFactory对HttpClient所做的改进,并给出了如何直接使用或以命名形式使用它的例子。但是,他们似乎都提到,利用类型化表单确实对其结构、可用性和更多方面是最好的。这些原因对于我们的用例是有意义的 尽管像上面提供的链接一样,在创建类型化的HttpClient(或作为客户端的服务)时,没有一行代码实例化、注入或使用IHttpClientFactory。创建类型化客户端: public class GitHubServic

在我看到的每一个例子中,包括微软的和,作者都解释了
IHttpClientFactory
HttpClient
所做的改进,并给出了如何直接使用或以命名形式使用它的例子。但是,他们似乎都提到,利用类型化表单确实对其结构、可用性和更多方面是最好的。这些原因对于我们的用例是有意义的

尽管像上面提供的链接一样,在创建类型化的
HttpClient
(或作为客户端的服务)时,没有一行代码实例化、注入或使用
IHttpClientFactory
。创建类型化客户端:

public class GitHubService
{
    public HttpClient Client { get; }

    public GitHubService(HttpClient client)
    {
然后在某个模型或控制器中使用它:

public TypedClientModel(GitHubService gitHubService)
{
    _gitHubService = gitHubService;
}

public async Task OnGet()
{
    try
    {
        LatestIssues = await _gitHubService.GetAspNetDocsIssues();
    }

我非常困惑。我的团队最初试图模拟(使用Moq)类型的客户机进行单元测试时遇到了一些障碍,经过大量的研究,我们得出的结论是,使用
IHttpClientFactory
进行模拟要容易得多。但是我还没有发现一个示例明确地将
IHttpClientFactory
用于类型化客户端。

框架将使用
itypedhtpclientfactory
创建要注入类型化客户端的
HttpClient
。当类型化客户端被配置为如下所示时,这种情况就会发生:

services.AddHttpClient<ICatalogService, CatalogService>()
类型化客户端也允许抽象客户端

public class GitHubService :IGitHubService { // <-- NOTE THE INTERFACE 
    HttpClient client

    public GitHubService(HttpClient client) {
        this.client = client;
    }

    //...
    
这里的优点是您与第三方依赖(框架关注点)分离,因为您是控制类型化客户机及其抽象的人


这将允许在隔离测试时更容易模拟类型化的客户端抽象。

使用
IHttpClientFactory
您有三个选项:

IHttpClientFactory 用法
公共类采样控制器
{
私有只读IHttpClientFactory\u客户端工厂;
公共采样控制器(IHttpClientFactory客户端工厂)
{
_clientFactory=clientFactory;
}
}
嘲笑
//排列
var mockClientFactory=new Mock();
var mockMessageHandler=new Mock();
mockMessageHandler.Protected()
.Setup(“sendsync”、ItExpr.IsAny()、ItExpr.IsAny())
.ReturnsAsync(预期响应消息);
var client=newhttpclient(mockMessageHandler.Object);
模拟客户工厂
.Setup(=>u.CreateClient(It.IsAny()))
.退货(客户);
命名客户 用法
公共类采样控制器
{
私有只读HttpClient\u客户端;
公共采样控制器(IHttpClientFactory客户端工厂)
{
_client=clientFactory.CreateClient(“SampleProxy”);
}
}
嘲笑 作为一个例子,我们可以通过使用定制的
HttpMessageHandler

公共类FakeMessageHandler:HttpMessageHandler
{
公共虚拟HttpResponseMessage发送(HttpRequestMessage请求)
{
抛出新的NotImplementedException();
}
受保护的覆盖任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
返回Task.FromResult(发送(请求));
}
}
//排列
var mockClientFactory=new Mock();
var mockMessageHandler=newmock{CallBase=true};
mockMessageHandler
.Setup(handler=>handler.Send(It.IsAny()))
.返回(预期响应消息);
var client=newhttpclient(mockMessageHandler.Object);
模拟客户工厂
.Setup(=>.CreateClient(“SampleProxy”))
.退货(客户);
类型化客户端 用法
公共类采样控制器
{
私有只读ISampleClient\u客户端;
公共采样控制器(ISampleClient客户端)
{
_客户=客户;
}
}
嘲笑
//排列
var clientMock=new Mock();
clientMock
.Setup(client=>client.GetXYZ(It.IsAny()))
.ReturnsAsync(预期采样响应);
var SUT=新的SampleController(clientMock.Object);

如果插入客户端接口而不是实现,那么测试/模拟可能会更容易。AddHttpClient有一个重载,允许以这种方式注册:类型化客户端是一种特殊情况,框架将使用工厂创建要注入类型客户端的HttpClient。“框架将使用工厂创建要注入类型客户端的HttpClient。”如何?哪里这就是我试图解开的正在发生的魔法。文章和资料都提到了它,但它非常复杂。@8protons类型的客户端只是通过DI应用的一种方便模式。您可以浏览扩展的源代码,并深入到IHttpClientFactory最终注册和使用的位置:这里是它最终使用工厂创建客户端的位置:
public class GitHubService :IGitHubService { // <-- NOTE THE INTERFACE 
    HttpClient client

    public GitHubService(HttpClient client) {
        this.client = client;
    }

    //...
    
services.AddHttpClient<IGitHubService, GitHubService>();
//...

private readonly IGitHubService gitHubService;

public TypedClientModel(IGitHubService gitHubService) {
    this.gitHubService = gitHubService;
}

public async Task OnGet() {
    try {
        LatestIssues = await gitHubService.GetAspNetDocsIssues();
    }

//...