C# 注入的HttpClient忽略IHttpClientFactory配置
我创建了一个自定义库,它可以自动为依赖于C# 注入的HttpClient忽略IHttpClientFactory配置,c#,dependency-injection,dotnet-httpclient,C#,Dependency Injection,Dotnet Httpclient,我创建了一个自定义库,它可以自动为依赖于HttpClient的特定服务设置Polly策略 这是使用扩展方法和类型化客户端方法来完成的。一个简化的例子: 公共静态IHttpClientBuilder设置FooServiceHttpClient(此IServiceCollection服务) { 回程服务 .AddHttpClient() .AddPolicyHandler(GetRetryPolicy()); } 示例服务: 公共类服务 { 私有只读HttpClient\u客户端; //选择1
HttpClient
的特定服务设置Polly策略
这是使用扩展方法和类型化客户端方法来完成的。一个简化的例子:
公共静态IHttpClientBuilder设置FooServiceHttpClient(此IServiceCollection服务)
{
回程服务
.AddHttpClient()
.AddPolicyHandler(GetRetryPolicy());
}
示例服务:
公共类服务
{
私有只读HttpClient\u客户端;
//选择1
公共服务(HttpClient HttpClient)
{
_client=httpClient;
}
//选择2
公共食品服务(IHttpClientFactory httpClientFactory)
{
_client=httpClientFactory.CreateClient(GetType().Name);
}
公共职务
{
var test=\u client.GetAsync(“http://example.com");
}
}
从DI容器(这是从测试项目)获取服务:
var services=newservicecolection();
SetUpFooServiceHttpClient();
services.AddSingleton();
var fooService=服务
.BuildServiceProvider()
.GetRequiredService();
//执行测试
fooService.DoJob();
注意:在这个测试项目中,我还添加了一个额外的模拟处理程序,因为我试图模拟http状态响应,但是模拟处理程序是否存在与Polly策略是否存在完全相同,所以我在示例代码中省略了模拟处理程序
请注意FooService
中的两个不同构造函数。根据我对哪一个进行了评论和留下了哪一个,我会得到不同的结果。所有其他代码保持不变
- 选项1,直接注入
,忽略我的所有配置。我得到了一个没有Polly策略处理程序的标准http客户机HttpClient
- 选项2,注入
并使用当前类型名称请求客户端(即IHttpClientFactory
)符合我的配置。我得到一个自定义http客户端,其中包含Polly策略处理程序(以及我可能配置的任何其他处理程序,例如测试套件中的模拟处理程序)FooService
HttpClient
。但事实并非如此
我找到的文档指定在使用类型化的客户端时可以注入HttpClient
:
- 例如,“类型化客户机”部分
- 这个
- 这个
HttpClient
显然不适合我
为什么注入
HttpClient
与注入IHttpClientFactory
在我的情况下效果不同?实际上,您的FooService
类有以下两种注册:
services.AddHttpClient()
services.AddSingleton()代码>
由于DI容器在幕后的工作方式,第二次注册覆盖了第一次注册。如果删除第二个注册,将使用第一个注册,因此将调用带有
HttpClient
参数的构造函数。removeservices.AddSingleton()代码>-您不需要它,它实际上覆盖了前面的AddTypedClient
调用完成的一些配置。“我想这可能就是你们所需要解决的所有问题了。”柯克拉金奖得主,鸡肉晚餐!发布一个答案,我会在可能的时候接受+赏金。这确实让事情有点复杂,因为这意味着我的图书馆的消费者不允许建立他们自己的服务。当他们想要注册
,
,
,以及整个作用域/瞬态/单例逻辑时,这会很烦人。反转两行(而不是删除一行)会起作用吗?只是为了兴趣。@mjwills:它确实有效,但第一行实际上被忽略了。刚刚通过设置调试值对其进行了测试,我注意到在添加类型化客户端之后,我预先设置的任何FooService
依赖项配置都不再存在,注入的依赖项是“默认”的FooService
实例,注入了正确的httpclient。总的来说,DI框架的行为感觉比它应该的更挑剔,但至少它现在可以工作:)只是为了稍微扩展一下,为将来的读者,通过删除AddSingleton
行,HttpClient
方法是固定的,但是IHttpClientFactory
方法中断了。您应该仅为那些依赖于IHttpClientFactory
的类调用AddSingleton
(及类似)。