我试图了解
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
来自文档:
将 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
时发生的负面影响。
我发现这篇文章有助于加深我对
IHttpClientFactory
模式的理解。
在ConfigureServices方法中定义类型化客户端时, 类型化服务是在瞬态范围内注册的。这意味着一个 每次需要时,DI 容器都会创建新实例。 发生这种情况的原因是 [sic] HttpClient 实例被注入到 类型化的客户端实例。 该 HttpClient 实例的目的是 生命周期较短,以便 HttpClientFactory 可以确保 底层处理程序(和连接)被释放和回收。