共计 5335 个字符,预计需要花费 14 分钟才能阅读完成。
利用 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 我的项目。
- 启动 Visual Studio IDE。
- 点击“创立新我的项目”。
- 在“创立新我的项目”窗口中,从模板列表中抉择 ASP.NET Core Web 应用程序。
- 单击 Next。
- 在“配置新我的项目”窗口中,指定新我的项目的名称和地位。
- 能够抉择“将解决方案和我的项目放在同一个目录中”复选框。
- 点击 Create。
- 在“创立一个新的 ASP.NET Core Web 应用程序“窗口中,抉择。NET Core 作为运行时,而后抉择 asp.net Core 作为运行时。NET Core 3.1(或更高版本)。
- 抉择“Web Application (Model-View-Controller)”作为我的项目模板来创立一个新的 ASP.NET Core MVC 应用程序。
- 确保复选框“启用 Docker 反对”和“配置 HTTPS”没有选中,因为咱们不会在这里应用这些个性。
- 确保身份验证设置为“无身份验证”,因为咱们也不会应用身份验证。
- 单击 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 还负责解决一些常见问题,比方日志记录。