依赖注入:HttpClient 还是 HttpClientFactory?

pro*_*cma 33 c# dependency-injection dotnet-httpclient asp.net-core

我到处都可以看到在 DI 中创建客户端的三种主要方法(基本的、命名的、类型化的),但我找不到注入IHttpClientFactoryHttpClient(两者都可能)的地方。

Q1 : 注射IHttpClientFactoryHttpClient请有什么区别?

Q2:如果IHttpClientFactory被注入,我应该factory.CreateClient()在每次调用时使用吗?

edo*_*o.n 38

概括

  • HttpClient只能注入Typed客户端
  • 对于其他用途,您需要 IHttpClientFactory
  • 在这两种情况下, 的生命周期HttpClientMessageHandler都由框架管理,因此您不必担心(错误地)处置HttpClients.

例子

为了直接注入HttpClient,你需要注册一个特定的Typed服务来接收客户端:

services.AddHttpClient<GithubClient>(c => c.BaseAddress = new System.Uri("https://api.github.com"));
Run Code Online (Sandbox Code Playgroud)

现在我们可以将它注入到类型化的GithubClient 中

public class GithubClient
{
    public GithubClient(HttpClient client)
    {
        // client.BaseAddress is "https://api.github.com"
    }
}
Run Code Online (Sandbox Code Playgroud)

你不能注入HttpClientinside AnotherClient,因为它没有输入AnotherClient

public class AnotherClient
{
    public AnotherClient(HttpClient client)
    {
        // InvalidOperationException, can't resolve HttpClient 
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,您可以:
1. 注入IHttpClientFactory并调用CreateClient()。此客户端将BaseAddress设置为null
2. 或者配置AnotherClient为不同类型的客户端,例如,不同的BaseAdress.

更新

根据您的评论,您正在注册一个命名客户端。它仍然是从 IHttpClientFactory.CreateClient() 方法解析的,但您需要传递客户端的“名称”

登记

services.AddHttpClient("githubClient", c => c.BaseAddress = new System.Uri("https://api.github.com"));
Run Code Online (Sandbox Code Playgroud)

用法

// note that we inject IHttpClientFactory
public HomeController(IHttpClientFactory factory)
{
    this.defaultClient = factory.CreateClient(); // BaseAddress: null
    this.namedClient = factory.CreateClient("githubClient"); // BaseAddress: "https://api.github.com"
}
Run Code Online (Sandbox Code Playgroud)


Dom*_*and 5

遗憾的是,我无法发表评论,只能发表答案。因此,我建议您应该查看以下链接:

https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests

https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

关于您的问题,它或多或少归结为:

Q1 -> IHttpClientFactory 处理 HttpClient 实例的连接池,如果 HttpClient 使用错误,这将帮助您处理链接中描述的加载和处理问题。

Q2 -> 是的,您应该根据 microsoft docs 使用 factory.create 客户端