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

Posted

技术标签:

【中文标题】如何将多个 HttpClient 参数传递/注入到类型化的 HttpClientClass?【英文标题】:How to pass/inject more than one HttpClient parameter to a typed HttpClientClass? 【发布时间】:2019-03-25 15:48:28 【问题描述】:

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

services.AddHttpClient();

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

public class MyHttpClient : IMyHttpClient

    public MyHttpClient (HttpClient httpClient, 
                         HttpClient refreshHttpClient)
    
    

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

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

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

【问题讨论】:

为什么有 2 个?你能把那个隐藏在另一个打字客户端后面吗? 如果我这样做了,那么我需要创建一个常规类来接收两个客户端实现来编排我需要的一切。我想做一件事情。在我的场景中,我想调用一个端点,但在此之前我想看看我是否需要刷新一个令牌,这需要通过另一个 http 通道调用来完成 FWIW,这违反了 SRP(单一责任原则)。这里有两组不同的逻辑,它们为两个不同的类尖叫。我什至会说三个类。一个与您的实际HttpClient 一起工作,一个用于刷新,然后一个第三个 来协调两者。第三个是你实际注入到控制器等地方的那个。 httpClientrefreshHttpClient 究竟有何不同?不清楚为什么需要两个。 HttpClient 类是线程安全的,所以你应该能够将它用于 ping 和发现,除非有一些区别。 @JhonWu 发现端点与 HttpClient 应该做的端点不同 【参考方案1】:

你不能。你要么需要注入另一个服务层,要么直接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;
    

然后:

services.AddHttpClient<MyRefreshClient>(c =>  ... );
services.AddHttpClient<MyHttpClient>(c =>  ... );

注入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");
    

然后:

services.AddHttpClient("MyHttpClient", c =>  ... );
services.AddHttpClient("MyRefreshClient", c=>  ... );

【讨论】:

我想将用户名和密码作为string 的参数传递,但我不知道该怎么做,但您的回复建议我可以使用Options 对象并注入它。跨度>

以上是关于如何将多个 HttpClient 参数传递/注入到类型化的 HttpClientClass?的主要内容,如果未能解决你的问题,请参考以下文章

在 Angularjs 中 ui-sref 和 $state.go 如何传递单个多个参数和将对象作为参数

使用依赖注入管理多个 HttpClient 实例

httpclient如何传递数组参数

Angular 12 Httpclient jsonp - 如何传递自定义回调参数?

SwiftUI:如何将 NSManagedObjectContext 传递到多个视图模型中

如何在静态方法或自定义类中注入 HttpClient?