使用services.AddHttpClient时,HttpClient是在哪里创建的?

问题描述 投票:0回答:2

我试图了解

HttpClient
是如何在 Nop Commerce 中实现验证码的,并且为了可测试性,如何在 Nop Commerce 项目中管理创建
HttpClient
的新实例。

我遇到了

ValidateCaptchaAttribute
ValidateCaptchaFilter
,我看到 HttpClient 已被包装在
CaptchaHttpClient
类中 但我不明白
CaptchaHttpClient
从哪里接收
HttpClient
的依赖关系以及从哪里调用
CaptchaHttpClient
类的构造函数。

ServiceCollectionExtensions
类中我看到下面的代码:

public static void AddNopHttpClients(this IServiceCollection services)
 {
    //default client
    services.AddHttpClient(NopHttpDefaults.DefaultHttpClient).WithProxy();

    //client to request current store
    services.AddHttpClient<StoreHttpClient>();

    //client to request nopCommerce official site
    services.AddHttpClient<NopHttpClient>().WithProxy();

    //client to request reCAPTCHA service
    services.AddHttpClient<CaptchaHttpClient>().WithProxy();
 }

但是我没有看到 HttpClient 对象是在哪里创建的:

var client = new HttpClient() // Where this is done?

我可能错过了什么吗?

Nop 商务版本 = 4.20

c# .net asp.net-core-mvc nopcommerce
2个回答
47
投票

来自文档

将 IHttpClientFactory 和相关服务添加到 IServiceCollection 并配置 TClient 类型和命名的 HttpClient 之间的绑定。客户端名称将设置为 TClient 的类型名称。

粗略翻译,

services.AddHttpClient<CaptchaHttpClient>()
意味着
CaptchaHttpClient
依赖于
HttpClient
。这表示,当将
HttpClient
注入
CaptchaHttpClient
时,不要只是创建一个新的 - 使用
IHttpClientFactory
的实现来提供一个并注入它创建的
HttpClient

这意味着您没有管理

HttpClient
的生命周期。
ServiceProvider
正在幕后做这件事。 (您也不负责创建客户端工厂。)

本文档解释了为什么存在以及它是如何工作的。

类型化客户端实际上是一个瞬态对象,这意味着每次需要时都会创建一个新实例,并且每次构造时都会收到一个新的 HttpClient 实例。然而,池中的 HttpMessageHandler 对象是被多个 Http 请求复用的对象。

这意味着:

  • 您正在注册的东西 - 在本例中
    CaptchaHttpClient
    是暂时的,因此每次解析时都会创建一个新实例。
  • 每次创建时,都会创建并注入一个新的
    HttpClient
  • 虽然
    HttpClient
    是新的,但是它所依赖的
    HttpMessageHandler
    是被复用的。

这使用了我们无需管理的

HttpMessageHandler
实例池。我们的类只依赖于
HttpClient
,而不必担心每次需要时创建/处置
HttpClient
时发生的负面影响。


6
投票

我发现这篇文章有助于加深我对

IHttpClientFactory
模式的理解。

在ConfigureServices方法中定义类型化客户端时, 类型化服务是在瞬态范围内注册的。这意味着一个 每次需要时,DI 容器都会创建新实例。 发生这种情况的原因是 [sic] HttpClient 实例被注入到 类型化的客户端实例。 该 HttpClient 实例的目的是 生命周期较短,以便 HttpClientFactory 可以确保 底层处理程序(和连接)被释放和回收。

© www.soinside.com 2019 - 2024. All rights reserved.