如何将多个 HttpClient 参数传递/注入到类型化的 HttpClientClass?

Zin*_*nov 4 c# dependency-injection dotnet-httpclient .net-core asp.net-core

我想在此处注册一个类型化的 HttpClient Microsoft docs。基本上,该方法应该是

services.AddHttpClient();

通常,这些类的模式仅接收 HttpClient 类作为参数,并且您实现调用端点的逻辑。就我而言,我需要在 MyHttpClient 中使用 2 个 HttpClient,一个 ping 端点,另一个与 IdentityProvider 对话以发现 refreshEndpoints 以刷新我的 cookie。

public class MyHttpClient : IMyHttpClient
{
    public MyHttpClient (HttpClient httpClient, 
                         HttpClient refreshHttpClient)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我试图从控制器解析 IMyHttpClient,我会收到一条错误消息,指出它无法解析 HttpClient。

在第 43 行AddHttpClient的 GitHub 代码中,您可以看到它正在调用 DefaultTypedHttpClientFactory。如果您转到DefaultTypedHttpClientFactory 实现的实现,您会注意到它是一个泛型类型。当它调用 CreateClient 时,它只向第 39 行的构造函数传递一个参数。

我在这里看到的唯一解决方法是不创建类型化客户端并注册接收 IHttpClientFactory 的普通类,并动态创建和配置我的客户端,而不是类型化。还有其他想法吗?

Chr*_*att 5

你不能。您要么需要注入另一个服务层,要么IHttpClientFactory直接注入

另一项服务

public class MyRefreshClient
{
    private readonly HttpClient _httpClient;

    public MyRefreshClient(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    ...
}

public class MyHttpClient : IMyHttpClient
{
    private readonly HttpClient _httpClient;
    private readonly MyRefreshClient _refreshClient;

    public MyHttpClient(HttpClient httpClient, MyRefreshClient refreshClient)
    {
        _httpClient = httpClient;
        _refreshClient = refreshClient;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

services.AddHttpClient<MyRefreshClient>(c => { ... });
services.AddHttpClient<MyHttpClient>(c => { ... });
Run Code Online (Sandbox Code Playgroud)

注入IHttpClientFactory(并使用命名客户端)

public class MyHttpClient : IMyHttpClient
{
    private readonly HttpClient _httpClient;
    private readonly HttpClient _refreshClient;

    public MyHttpClient(IHttpClientFactory httpClientFactory)
    {
        _httpClient = httpClientFactory.CreateClient("MyHttpClient");
        _refreshClient = httpClientFactory.CreateClient("MyRefreshClient");
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

services.AddHttpClient("MyHttpClient", c => { ... });
services.AddHttpClient("MyRefreshClient", c=> { ... });
Run Code Online (Sandbox Code Playgroud)