ASP.NET Core 5.0 中DI注入的HttpClient未携带已配置的BaseAddress与请求头
问题根因
这个问题完全是重复注册ToornamentService导致的依赖绑定覆盖,和IHttpClientFactory本身的逻辑无关。
你调用services.AddHttpClient<ToornamentService>(c => {...})的时候,这个扩展方法本身已经完成了两套绑定:
- 把
ToornamentService以Scoped生命周期注册到DI容器 - 自动生成带指定
BaseAddress、默认API密钥请求头的HttpClient实例,并且约定将这个配置好的实例注入到ToornamentService的构造函数里
但你紧接着写的services.AddTransient<ToornamentService>();直接把前面的注册给覆盖掉了。现在DI容器解析ToornamentService的时候,会优先走你手动声明的Transient注册逻辑——这个逻辑根本没和之前配置好的专属HttpClient做关联,只会从容器里匹配可注入的HttpClient实例。由于你从来没单独注册过带自定义配置的HttpClient,最终拿到的就是无任何配置的默认实例,自然BaseAddress是null、自定义请求头也不存在。
修复方法
直接删掉那行多余的services.AddTransient<ToornamentService>();就行。
几个容易踩的相关坑提醒:
- 凡是通过
AddHttpClient<TClient>()注册的强类型服务,绝对不要再手动给TClient加任何生命周期注册(不管是Transient、Scoped还是Singleton),不然会直接覆盖原有工厂绑定逻辑 - 你之前试换IHttpClientFactory方案拿到同样结果,本质也是同一个问题:大概率是注册服务的时候,没有用
CreateClient()获取对应配置的HttpClient,反而直接从DI里拿了无配置的实例 - 删掉重复注册后再调试,就能看到构造函数里的HttpClient已经带了完整的BaseAddress和API密钥请求头
额外提示:很多人写注册代码的时候习惯把所有服务都手动列一遍生命周期,碰到HttpClient工厂注册的强类型服务再重复加一行AddTransient,这是最常见的踩坑点。
内容的提问来源于stack exchange,提问作者Nicolas Van Damme
相关产品推荐
相关产品推荐

