C# 使用services.AddHttpClient时,HttpClient在哪里创建?

C# 使用services.AddHttpClient时,HttpClient在哪里创建?,c#,asp.net-core-mvc,nopcommerce,C#,Asp.net Core Mvc,Nopcommerce,我试图了解在Nop商务中如何为验证码实现HttpClient,以及为了可测试性,如何在Nop商务项目中管理创建HttpClient的新实例 我遇到了ValidateCaptchaAttribute和ValidateCaptchaFilter,我看到HttpClient被包装在CaptchaHttpClient类中 但是我不明白从哪里CaptchaHttpClient接收HttpClient的依赖项,以及从哪里调用CaptchaHttpClient类的构造函数 在ServiceCollection

我试图了解在Nop商务中如何为验证码实现
HttpClient
,以及为了可测试性,如何在Nop商务项目中管理创建
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();
 }
我是不是错过了什么

Nop商业版=4.20

来源:

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

大致翻译为,
services.AddHttpClient()
意味着
CaptchaHttpClient
依赖于
HttpClient
。这意味着在将
HttpClient
注入
captchahtpclient
时,不要仅仅创建一个新的客户端-使用
IHttpClientFactory
的实现来提供一个并注入它

这意味着您没有管理
HttpClient
的生命周期。
ServiceProvider
正在幕后进行这项工作

解释了为什么存在这种情况以及它是如何工作的

类型化客户机实际上是一个临时对象,这意味着每次需要一个实例时都会创建一个新实例,并且每次构造一个新的HttpClient实例时,它都会收到一个新的HttpClient实例。但是,池中的HttpMessageHandler对象是多个Http请求重用的对象

这意味着:

  • 您正在注册的东西—在本例中,
    CaptchaHttpClient
    是暂时的,因此每次解决它时,都会创建一个新实例
  • 每次创建时,都会创建并注入一个新的
    HttpClient
  • 尽管
    HttpClient
    是新的,但它所依赖的
    HttpMessageHandler
    将被重用
这使用了一个不需要管理的
HttpMessageHandler
实例池。我们的课程只依赖于
HttpClient
,而不必担心每次需要时创建/处理
HttpClient
时会产生负面影响。

我发现这有助于进一步理解
IHttpClientFactory
模式

在ConfigureServices方法中定义类型化客户端时 类型化服务已在临时作用域中注册。这意味着 每当需要一个实例时,DI容器就会创建一个新实例。 发生这种情况的原因是[sic]HttpClient实例被注入到 类型化的客户端实例该HttpClient实例旨在 寿命短,以便HttpClientFactory能够确保 底层处理程序(和连接)被释放和回收


非常感谢您的回答。这是否意味着AddHttpClient正在幕后开发新的HttpClient()。我认为这是因为开发人员错误地使用了
HttpClient
,但我不知道如何才能使它正确。现在我也在读这篇文章。最后一个文档链接真的很有帮助,也消除了我的一些疑问。非常感谢。但我仍然不知道WithProxy()的含义是什么?它是将HttpClient创建为Singleton对象还是它的具体功能?这是回到Nop源代码中的。显然,它从配置中获取一些代理设置,并将
HttpMessageHandler
配置为使用它们。无论从何处获取这些代理设置,如果未指定,则使用默认凭据。因此,虽然您可以决定是否在自己的代码中使用
WithProxy()
,但这是Nop的代码。因此,除非它们提供某种方法来覆盖所有这些配置,否则您只是在使用依赖项,不管它们是如何注册的。但是,由于除非配置设置提供代理凭据,否则它似乎不会执行任何操作,因此您似乎可以忽略它。
var client = new HttpClient() // Where this is done?