详解如何在ASP.NET Core中使用IHttpClientFactory

利用IHttpClientFactory可以无缝创建HttpClient实例,避免手动管理它们的生命周期。

当使用ASP.Net Core开发应用程序时,可能经常需要通过HttpClient调用WebAPI的方法以检查终结点是否正常工作。要实现这一点,通常需要实例化HttpClient并使用该实例来调用你的方法。但是直接使用HttpClient也有一些缺点,主要与手动管理实例的生命周期有关。

你可以使用IHttpClientFactory创建HttpClient来避免这些问题。IHttpClientFactory是在.Net Core 2.1引入的,它提供了一个命名,配置和创建HttpClient实例的核心功能,并能自动管理实例的池化和生命周期。

下面我们通过代码进一步讨论HttpClient和IHttpClientFactory,以及所设计的概念。要使用提供的代码,你需要安装Visual Studio 2019。

在Visual Studio 2019中创建一个ASP.NET Core MVC项目

假设你的系统中安装了Visual Studio 2019,请按照下面列出来的步骤创建一个新的ASP.NET Core项目。
1. 启动Visual Studio IDE。
2. 点击“创建新项目”。
3. 在“创建新项目”窗口中,从模板列表中选择ASP.NET Core Web应用程序。
4. 单击Next。
5. 在“配置新项目”窗口中,指定新项目的名称和位置。
6. 可以选择“将解决方案和项目放在同一个目录中”复选框。
7. 点击Create。
8. 在“创建一个新的ASP.NET Core Web应用程序“窗口中,选择。NET Core作为运行时,然后选择asp.net Core作为运行时。NET Core 3.1(或更高版本)。
9. 选择“Web Application (Model-View-Controller)”作为项目模板来创建一个新的ASP.NET Core MVC应用程序。
10. 确保复选框“启用Docker支持”和“配置HTTPS”没有选中,因为我们不会在这里使用这些特性。
11. 确保身份验证设置为“无身份验证”,因为我们也不会使用身份验证。
12. 单击Create。

按照这些步骤将创建一个新的ASP.NET Core MVC应用程序。在新项目中,创建一个新的API Controller,并使用默认名称保存它,即ValuesController。我们将在接下来的部分中使用这个项目。

挑战HttpClient

尽管HttpClient没有直接实现IDisposable接口,但它扩展了System.Net.Http。HttpMessageInvoker,这个类实现了IDisposable。然而,当使用HttpClient实例时,你不应该手动操作释放它们。尽管可以在HttpClient实例上调用Dispose方法,但不推荐这样做。
应该怎么做呢?一种选择是使HttpClient静态化,或者将HttpClient的非静态实例包装在自定义类中,并使其成为单例类。但是更好的替代方法是使用IHttpClientFactory来生成HttpClient的实例,然后使用该实例来调用操作方法。

IHttpClientFactory 和HttpClientFactory

IHttpClientFactory是一个由DefaultHttpClientFactory类实现的接口,这是一个工厂模式。DefaultHttpClientFactory实现了IHttpClientFactory和IHttpMessageHandlerFactory接口。IHttpClientFactory提供了ASP.NET Core对创建、缓存和处理HttpClient实例提供了出色的内置支持。
请注意,HttpClientFactory只是一个帮助类,用于创建使用提供的处理程序配置的HttpClient实例。这个类有以下方法:

Create(DelegatingHandler[])
Create(HttpMessageHandler,DelegatingHandler[])
CreatePipeline(HttpMessageHandler,IEnumerable<DelegatingHandler>)

重载的HttpClientFactory类的Create方法看起来像这样:

public static HttpClient Create(params DelegatingHandler[] handlers)
{
 return Create(new HttpClientHandler(), handlers);
}
public static HttpClient Create(HttpMessageHandler innerHandler, params DelegatingHandler[] handlers)
{
 HttpMessageHandler pipeline = CreatePipeline(innerHandler, handlers);
 return new HttpClient(pipeline);
}

引入HttpClientFactory和IHttpClientFactory是为了更好地管理HttpMessageHandler实例的生命周期。

为什么使用IHttpClientFactory?

当你释放HttpClient实例时,连接将保持打开状态长达4分钟。此外,可以在任何时间点打开socket的数量是有限制的——不能同时打开太多socket。因此,当使用太多HttpClient实例时,可能会耗尽socket。
这就是IHttpClientFactory的意义所在。你可以通过利用IHttpClientFactory来创建用于调用HTTP API方法的HttpClient实例,以避免HttpClient所面临的问题。在ASP.NET Core中实现IHttpClientFactory的主要目标是为了确保使用工厂模式创建HttpClient实例的同时避免socket耗尽。

在ASP.NET Core中注册IHttpClientFactory实例

你可以在Startup类的ConfigureServices方法中,通过调用IServiceCollection实例上的AddHttpClient扩展方法注册一个IHttpClientFactory类型的实例,如下:

public void ConfigureServices(IServiceCollection services)
{
  services.AddControllersWithViews();
  services.AddHttpClient();
}

将IHttpClientFactory实例注入到控制器

可以通过如下代码将将IHttpClientFactory实例注入到控制器:

public class HomeController : Controller
{
   private IHttpClientFactory _httpClientFactory;
   private readonly ILogger<HomeController> _logger;
   public HomeController(ILogger<HomeController> logger,
   IHttpClientFactory httpClientFactory)
   {
      _logger = logger;
      _httpClientFactory = httpClientFactory;
   }
}

在Action中调用HttpClient

要通过使用IHttpClientFactory创建HttpClient,应该调用CreateClient方法。一旦HttpClient实例可用,就可以在HomeController类的index方法中使用以下代码来调用ValuesController类的Get方法。

public async Task<IActionResult> Index()
{
  HttpClient httpClient = _httpClientFactory.CreateClient();
  httpClient.BaseAddress = new Uri("http://localhost:1810/");
  var response = await httpClient.GetAsync("/api/values");
  string str = await response.Content.ReadAsStringAsync();
  List<string> data = JsonSerializer.Deserialize<List<string>>(str);
  return View(data);
}

使用IHttpClientFactory在ASP.NET Core中创建和管理HttpClient实例

有几种方法可以在应用程序中使用IHttpClientFactory。这包括直接使用IHttpClientFactory、使用命名client和类型client。
基本的或一般的使用模式,即直接使用IHttpClientFactory—在前面的小节中已经讨论过了。请参考“注册一个IHttpClientFactory实例”一节,该节讨论了如何注册HttpClient实例。

如果你想使用不同配置的HttpClient实例,以下是一个不错的选择。下面的代码片段说明了如何创建。

services.AddHttpClient("github", c =>
{
  c.BaseAddress = new Uri("https://api.github.com/");
  c.DefaultRequestHeaders.Add("Accept",
  "application/vnd.github.v3+json");
  c.DefaultRequestHeaders.Add("User-Agent", "This is a test user agent");
});

第二种方法是使用包装了HttpClient实例的自定义类,该自定义类封装了通过HTTP协议调用所有终结点的逻辑。下面的代码片段说明了如何定义自定义HttpClient类。

public class ProductService : IProductService
{
  private IHttpClientFactory _httpClientFactory;
  private readonly HttpClient _httpClient;
  private readonly string _baseUrl = "http://localhost:1810/";
  public ProductService(HttpClient httpClient)
  {
    _httpClient = httpClient;
  }
  public async Task<Catalog> GetAllProducts()
  {
    _httpClient = _httpClientFactory.CreateClient();
    _httpClient.BaseAddress = new Uri(_baseUrl);
    var uri = "/api/products";
    var result = await _httpClient.GetStringAsync(uri);
    return JsonConvert.DeserializeObject<Product>(result);
  }
}

通过以下代码注册自定义的client:

services.AddHttpClient<IProductService, ProductService>();

将MessageHandler添加到命名管道中

MessageHandler是扩展自HttpMessageHandler类,它可以接受HTTP请求并返回HTTP响应。如果你想构建自己的MessageHandler,你应该创建一个继承DelegatingHandler的类。

你可以将HttpMessageHandler添加到请求处理管道中。可以在Startup类的ConfigureServices方法中使用以下代码将HttpMessageHandler添加到管道中。

public void ConfigureServices(IServiceCollection services)
{
  services.AddHttpClient("github", c =>
  {
    c.BaseAddress = new Uri("https://api.github.com/");
  })
  .AddHttpMessageHandler<DemoHandler>();
  services.AddTransient<DemoHandler>();
}

IHttpClientFactory是一个自.net Core 2.1以来就可用的工厂类。如果你使用IHttpClientFactory来创建HttpClient实例,那么底层HttpClientMessagehandler实例的池化和生命周期将自动管理。IHttpClientFactory还负责处理一些常见问题,比如日志记录。

到此这篇关于详解如何在ASP.NET Core中使用IHttpClientFactory的文章就介绍到这了,更多相关ASP.NET Core使用IHttpClientFactory内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Asp.Net Core2.1前后使用HttpClient的两种方式

    前言 在.Net Core应用开发中,调用第三方接口也是常有的事情,HttpClient使用人数.使用频率算是最高的一种了,在.Net Core中,HttpClient的使用方式随着版本的升级也发生了一些变化,本次就讲解一下Asp.Net Core2.1前后使用的两种方式. 一.原先HttpClient使用方式 一般来讲,喜欢要用的时候才会选择去获取资源,因此,当在有需求时才会用HttpClient去调用资源,便会使用如下这种方式或其它方式获取资源. //do something... usin

  • ASP.NET Core针对一个使用HttpClient对象的类编写单元测试详解

    介绍 几年前,微软引入了HttpClient类来替代HttpWebRequest来发送Web请求.这个新的类更易于使用,更加简洁,更具有异步性,且易于扩展. HttpClient类有一个可以接受HttpMessageHandler类对象的构造函数.HttpMessageHandler类对象可以接受一个请求(HttpRequestMessage), 并返回响应(HttpResponseMessage).它的功能完全取决于它的实现.默认情况下HttpClient使用的是HttpClientHandl

  • 详解如何在ASP.NET Core中使用IHttpClientFactory

    利用IHttpClientFactory可以无缝创建HttpClient实例,避免手动管理它们的生命周期. 当使用ASP.Net Core开发应用程序时,可能经常需要通过HttpClient调用WebAPI的方法以检查终结点是否正常工作.要实现这一点,通常需要实例化HttpClient并使用该实例来调用你的方法.但是直接使用HttpClient也有一些缺点,主要与手动管理实例的生命周期有关. 你可以使用IHttpClientFactory创建HttpClient来避免这些问题.IHttpClie

  • 详解如何在ASP.NET Core中编写高效的控制器

    通过遵循最佳实践,可以编写更好的控制器.所谓的"瘦"控制器(指代码更少.职责更少的控制器)更容易阅读和维护.而且,一旦你的控制器很瘦,可能就不需要对它们进行太多测试了.相反,你可以专注于测试业务逻辑和数据访问代码.瘦控制器的另一个优点是,它更容易维护控制器的多个版本. 这篇文章讨论了使控制器变胖的坏习惯,然后探索了使控制器变瘦和易于管理的方法.我列出编写控制器的最佳实践可能并不全面,但我已经讨论了最重要的一些,并在适当的情况下提供了相关的源代码.在接下来的几节中,我们将研究什么是胖控制

  • 详解如何在ASP.Net Core中实现健康检查

    健康检查 常用于判断一个应用程序能否对 request 请求进行响应,ASP.Net Core 2.2 中引入了 健康检查 中间件用于报告应用程序的健康状态. ASP.Net Core 中的 健康检查 落地做法是暴露一个可配置的 Http 端口,你可以使用 健康检查 去做一个最简单的活性检测,比如说:检查网络和系统的资源可用性,数据库资源是否可用,应用程序依赖的消息中间件或者 Azure cloud service 的可用性 等等,这篇文章我们就来讨论如何使用这个 健康检查中间件. 注册健康检查

  • 详解如何在ASP.NET Core中使用Route特性

    ASP.NET Core 中的 Route 中间件的职责在于将 request 匹配到各自 Route 处理程序上,Route 分两种:基于约定 和 基本特性 模式. 基于约定 模式的Route采用集中化的方式,而 基于特性 的方式允许你在 Action 或者 Controller 上单独定义,到底采用哪一种可以基于你自己的应用场景,本篇就来讨论如何使用 基于特性 模式. 创建 Controller 类 创建一个 DefaultController 类,新增如下代码. public class

  • 详解如何在ASP.NET Core中应用Entity Framework

    首先为大家提醒一点,.NET Core和经典.NET Framework的Library是不通用的,包括Entity Framework! 哪怎么办? 别急,微软为.NET Core发布了.NET Core版本的Entity Framework,具体配置方法与经典.NET Framework版本的稍有区别,下面的内容就为带领大家在ASP.NET Core中应用Entity Framework DB first. 注:目前部分工具处于Preview版本,正式版本可能会稍有区别. 前期准备: 1.推

  • 详解如何在ASP.NET Core中使用Redis

    Redis 是一个开源的内存中的数据结构存储系统,可以用作数据库.缓存和消息中间件.它支持多种类型的数据结构:字符串,哈希表,列表,集合,有序集等等. Redis 官方没有推出Windows版本,倒是由Microsoft Open Tech提供了Windows 64bit 版本支持. 如何在Windows机器上安装Redis=>下载安装文件Redis-x64-3.2.100.msi,安装完毕之后,打开service管理器,找到Redis服务,并将其启动.  前期准备: 1.推荐使用Visual

  • 详解如何在ASP.NET Core Web API中以三种方式返回数据

    在 ASP.NET Core 中有三种返回 数据 和 HTTP状态码 的方式,最简单的就是直接返回指定的类型实例,如下代码所示: [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { [HttpGet] public IEnumerable<WeatherForecast> Get() { var rng = new Random()

  • 详解如何在C#/.NET Core中使用责任链模式

    最近我有一个朋友在研究经典的"Gang Of Four"设计模式.他经常来询问我在实际业务应用中使用了哪些设计模式.单例模式.工厂模式.中介者模式 - 都是我之前使用过,甚至写过相关文章的模式.但是有一种模式是我还没有写过文章,即责任链模式. 什么是责任链?# 责任链模式(之前我经常称之为命令链模式)是一种允许以使用分层方式"处理"对象的模式.在维基百科中的经典定义是 在面向对象设计中,责任链模式是一种由命令对象源及其一系列处理对象组成的设计模式.每个处理对象包含了

  • 详解如何在VS2019和VScode中配置C++调用python接口

    why 看到这个标题有些人说了,为什么好好的C++你非要调用python?人家明明是两种语言呀! 但是在实际应用中,有时候会用到C/C++调用python来更简单地去完成一些功能,不然人家python为什么有一个文件夹叫include,里边全是.h文件呢? VScode中配置环境 首先是在VScode中为C++调用python接口配置环境,这里假设你已经配置好了c++编程环境! 1.配置step1 用快捷键Ctrl+Shift+X打开Extensions 商店,输入python,install:

  • 如何在ASP.NET Core中使用Session的示例代码

    ASP.NET Core 是一个跨平台,开源的,轻量级,高性能 并且 高度模块化的web框架,Session 可以实现用户信息存储从而可以在同一个客户端的多次请求之间实现用户追踪,在 ASP.Net Core 中可以使用 Microsoft.AspNetCore.Session 中间件来启用 Session 机制. 中间件的价值在于可以在 request -> response 的过程中做一些定制化的操作,比如说:监视数据,切换路由,修改流转过程中的消息体,通常来说:中间件是以链式的方式灌入到

随机推荐