注入的 HttpClient 忽略 IHttpClientFactory 配置

Fla*_*ter 6 c# dependency-injection dotnet-httpclient polly

我创建了一个自定义库,它会自动为依赖于HttpClient.

这是使用IServiceCollection扩展方法和类型化客户端方法来完成的。一个简化的例子:

public static IHttpClientBuilder SetUpFooServiceHttpClient(this IServiceCollection services)
{
    return services
            .AddHttpClient<FooService>()
            .AddPolicyHandler(GetRetryPolicy());
} 
Run Code Online (Sandbox Code Playgroud)

示例服务:

public class FooService
{
    private readonly HttpClient _client;

    // OPTION 1
    public FooService(HttpClient httpClient)
    {
        _client = httpClient;
    }

    // OPTION 2
    public FooService(IHttpClientFactory httpClientFactory)
    {
        _client = httpClientFactory.CreateClient(GetType().Name);
    }

    public void DoJob()
    {
         var test = _client.GetAsync("http://example.com");
    }
}
Run Code Online (Sandbox Code Playgroud)

从 DI 容器中获取服务(来自测试项目):

var services = new ServiceCollection();

services.SetUpFooServiceHttpClient();
        
services.AddSingleton<FooService>();

var fooService = services
                   .BuildServiceProvider()
                   .GetRequiredService<FooService>();

// Perform test
fooService.DoJob();
Run Code Online (Sandbox Code Playgroud)

注意:在这个测试项目中,我还添加了一个额外的模拟处理程序,因为我试图模拟 http 状态响应,但模拟处理程序是否存在与 Polly 策略是否存在相同,因此我省略了模拟处理程序从示例代码。

请注意 中的两个不同的构造函数FooService。根据我注释掉哪一项和保留哪一项,我会得到不同的结果。所有其他代码保持不变。

  • 选项 1,直接注入HttpClient,忽略我的所有配置。我得到一个标准的 http 客户端,没有 Polly 策略处理程序。
  • 选项2,使用当前类型名称(即)注入IHttpClientFactory并请求客户端FooService尊重我的配置。我得到一个自定义 http 客户端,其中包含 Polly 策略处理程序(以及我可能配置的任何其他处理程序,例如我的测试套件中的模拟处理程序)

在这两种情况下都使用调试检查来确认策略处理程序的不存在/存在。

根据我找到的有关该主题的所有文档,这两个选项应该是等效的,至少就HttpClient我最终获得的构造而言是这样。但这里的情况并非如此。

我找到的文档指定可以在使用类型化HttpClient客户端时注入:

我正在使用类型化客户端,但注入HttpClient显然对我不起作用。

为什么在我的情况下注入 aHttpClient与注入的IHttpClientFactory效果不同?

Kir*_*kin 9

实际上,您的FooService课程有以下两项注册:

  1. services.AddHttpClient<FooService>()
  2. services.AddSingleton<FooService>();

由于 DI 容器在幕后工作的方式,第二个注册会覆盖第一个。如果删除第二个注册,则将使用第一个注册,因此HttpClient将调用带有参数的构造函数。

  • 只是为了为未来的读者稍微扩展一下,通过删除“AddSingleton”行,“HttpClient”方法被修复,但“IHttpClientFactory”方法被破坏。您应该仅对那些依赖于“IHttpClientFactory”的类调用“AddSingleton”(和类似的)。 (2认同)