c# - .net 核心中的 IHttpClientFactory

标签 c# asp.net-core

我想在我的 .NET Core 项目中使用 IHttpClientFactory。问题是我需要使用大量的 API。那么我应该为所有 API 使用单一的 Typed Client 还是应该将它们分开?所有 API 请求都发往同一来源。

public interface IStudentClient
{

}

public class StudentClient : IStudentClient
{

}

services.AddHttpClient<IStudentClient, StudentClient>();

我已遵循上述结构并计划将所有 API 包含在 IStudentClient 中并在 StudentClient 中实现它们。现在我的问题是,如果只在一个类中包含所有 API 的实现,这是否会使 StudentClient 类变得更复杂。

最佳答案

在我看来,为所有对特定远程服务的访问编写一个大类型的客户端是正确的方法。这正是 Microsoft 为类型化的 http 客户端设想的使用模式。

同时我理解你的担忧,但情况并没有你想象的那么绝望。

首先你会得到一个巨大的接口(interface),然后是一个巨大的实现类,但它们的职责很明确:类型化的客户端有责任定义一个代理来访问远程网络服务(学生服务在你的例子)。

类型化的客户端类实际上并不复杂:它可以是巨大的,当然,但它是无状态的,只是公开了访问远程 Web 服务端点的方法。每个方法都有明确且定义明确的职责:访问远程 Web 服务上的特定端点;像这样的代码很少复杂。

唯一需要注意的是使用接口(interface) IStudentClient从 Controller 或服务。接口(interface)很大,所以如果你将它作为依赖项注入(inject)到消费者类中,你将违反 interface segregation principle .这个问题的一个可能的解决方案是为更小的接口(interface)建模,为消费者类的特定需求而设计。

想象一下,您的远程 Web 服务公开的端点之一允许您获取单个学生的详细信息(可能类似于 GET/students/{studentId})。这意味着 IStudentClient 公开的方法之一。将是 GetStudentById(Guid studentId)它将 GET 请求包装到 /students/{studentId} .

此时您可以定义一个较小的接口(interface),称为IStudentProvider。 ,形状如下:

public interface IStudentProvider
{
  StudentContract GetstudentById(Guid studentId);
}

现在你可以注入(inject)较小的界面了IStudentProvider在您的消费者类中(例如,您在应用程序中定义的 MVC Controller 或服务类)。

实现接口(interface)IStudentProvider您可以执行以下操作:

public class HttpStudentProvider : IStudentProvider 
{
  private readonly IStudentClient client;

  public HttpStudentProvider(IStudentClient client)
  {
    this.client = client;
  }

  public StudentContract GetstudentById(Guid studentId) 
  {
    return this.client.GetStudentById(studentId);
  }
}

重要免责声明:为了使讨论简单,我没有使用 Task接口(interface)上的类,但当然所有方法都应返回 Task<T>并接受 CancellationToken 的实例作为参数,因为 http 调用是自然的异步操作,您希望通过您的 http 客户端执行阻塞调用。

如何在DI容器上注册这些类

Microsoft DI 容器将为您提供一些扩展方法来注册类型化客户端。该服务将被注册为 transient 依赖项,因此依赖于它的每个其他服务也必须注册为 transient 依赖项(以避免 captive dependency issue )。

这是您注册服务的方式:

public void ConfigureServices(IServiceCollection services)
{
   services.AddHttpClient<IStudentClient, StudentClient>();
   services.AddTransient<IStudentProvider, HttpStudentProvider>();
}

关于c# - .net 核心中的 IHttpClientFactory,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56897593/

相关文章:

c# - 如何替换自定义 appsettings.json 文件中的列表项?

c# - 开拓者 : how to bind Nullable object to <select>?

c# - 新 Visual Studio 2019 中的环境变量为空,但 Visual Studio 2017 中没有

c# - 通过 PKCS#11 提取公钥值

c# - 写文件时App崩溃或关闭怎么办?

c# - 如何按角色进行不同登录 ASP.NET Core 2.2

c# - 如何要求 HTTPS 但不重定向

c# - 无限数量的子弹

c# - Marshal.Copy,将一个 IntPtr 数组复制到一个 IntPtr

c# - 将图像转换为 base64,反之亦然