RestSharp v107 .NET依赖注入方案及DNS解析问题咨询
RestSharp 107 .NET 依赖注入方案结论
两种写法都能用,不存在功能性问题,只是适用场景和表现有区别,针对你问的几个点直接说结论:
两种方案的实际表现
- 第一种官方文档给的单例写法:
符合官方“不要每次请求新建RestClient”的要求,不会触发套接字连接池耗尽的问题。但有个很容易踩的坑:这种默认构造出来的RestClient,内部持有的HttpMessageHandler是和单例对象同生命周期的,长驻内存不会自动重建,默认感知不到DNS变更,如果你的下游服务会做IP切换(比如云服务故障切流、蓝绿发布换节点),很容易出现请求打到旧IP失败的情况。services.AddSingleton<IMyClient, MyClient>(); public class MyClient : IMyClient { protected readonly RestClient _restClient; public MyClient() { _restClient = new RestClient(); } } - 第二种用
AddHttpClient注入的写法:
完全可行,甚至是更推荐生产环境用的写法。你说的没错,AddHttpClient默认确实是给注册的服务用瞬态生命周期,但这里不用怕出问题:- 你注入拿到的HttpClient,背后是IHttpClientFactory做池化管理的,核心的HttpMessageHandler链会按默认2分钟的周期自动重建,这个机制天然解决了长生命周期HttpClient不感知DNS变更的问题。
- 哪怕MyClient、RestClient、注入的HttpClient都是瞬态的,每次请求新建这些对象,也不会导致连接池耗尽——因为最核心的、持有套接字连接的Handler是池化复用的,根本不会重复创建非托管连接资源。
services.AddHttpClient<IMyClient, MyClient>(); public class MyClient : IMyClient { protected readonly RestClient _restClient; public MyClient(HttpClient httpClient) { _restClient = new RestClient(httpClient); } }
你关心的两个细节问题
- 瞬态对象的性能开销:对通用业务应用来说完全可以忽略。不管是MyClient还是RestClient,本身都是纯托管的轻量对象,实例化过程没有昂贵的IO或者非托管资源分配操作,单次创建耗时在微秒级以内,哪怕是每秒几千请求的业务规模,这点开销占比连0.01%都到不了,根本不需要做额外优化。
- DNS感知能力:用
AddHttpClient的方案,哪怕上层的RestClient是瞬态创建的,因为底层Handler由IHttpClientFactory统一管理周期,到期自动重建,完全可以正常感知DNS变更,不会出现长连接绑死旧IP的问题。
小提示:用第二种方案的时候,不要手动去修改RestClient实例里和HttpMessageHandler相关的配置,不然会破坏IHttpClientFactory的池化逻辑,反而引出不必要的问题。
内容的提问来源于stack exchange,提问作者Paul McTigue
相关产品推荐
相关产品推荐

