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();
}
//...