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

     2023-03-30     296

关键词:

【中文标题】使用依赖注入管理多个 HttpClient 实例【英文标题】:Managing multiple instances of HttpClient using Dependency Injection 【发布时间】:2016-11-20 13:27:54 【问题描述】:

我正在为我的 Web 应用程序与之通信的每个不同 API 创建一个 HttpClient 实例。

我想使用 SimpleInjector 的依赖注入将 HttpClient 注入业务类。例如,我有ITwitterBusinessIInstagramBusiness,它们都在构造函数中接受HttpClient

在使用依赖注入注册多个相同类型的对象时,最佳实践是什么?

我很确定问题的一部分可能是我的设计,但这里有一些想法。

我的第一个想法是在 DI 注册中使用委托

container.Register<ITwitterBusiness>(() => new TwitterBusiness(httpClientTwitter));

看起来很简单,但我不知道这种方法是否有任何不良副作用,例如使 SimpleInjector 运行速度变慢,或者我是否破坏了某些设计模式。

我的第二个想法是使用基于上下文的注入 http://simpleinjector.readthedocs.io/en/latest/advanced.html#context-based-injection

我相信这将允许我将某个 HttpClient 实例注入某个类。仍然不确定这是如何工作的。

我很好奇我是否可以完全通过设计来解决这个问题。例如通过创建虚拟类。我只是没有找到任何好的例子,但如果我理解正确,那么我可以创建继承HttpClient 的虚拟类,例如HttpClientTwitter,这样我就可以摆脱模棱两可的注册。

谢谢!

【问题讨论】:

【参考方案1】:

我的第一个想法是在 DI 注册中使用委托。看起来很简单,但我不知道这种方法是否有任何不良副作用,例如使 SimpleInjector 运行速度变慢,或者我是否破坏了某些设计模式。

如果类型有任何需要连接的应用程序组件,建议使用自动连接(与注册委托相反)。自动连接简化了注册并允许 Simple Injector 分析对象图。在您的情况下,两者似乎都无关紧要。 HttpClient 不是应用程序组件,而是基础架构类型。似乎没有其他依赖项,因此注册委托不会造成任何可维护性问题。

与使用自动装配相比,委托注册速度较慢,Simple Injector 无法使用委托进行尽可能多的优化。但是,您在执行此操作时非常、非常不太可能注意到任何性能差异。这不是您应该担心的事情。

我的第二个想法是使用基于上下文的注入。我相信这将允许我将某个 HttpClient 实例注入某个类。仍然不确定这是如何工作的。

您可以根据上下文进行不同的注册。例如:

var httpClientTwitterRegistration = Lifestyle.Transient.CreateRegistration<HttpClient>(
    () => new HttpClient("https://twitter"),
    container);

container.RegisterConditional(typeof(HttpClient), httpClientTwitterRegistration,
    c => c.Consumer.ImplementationType == typeof(TwitterBusiness));

var httpClientInstagramRegistration = Lifestyle.Transient.CreateRegistration<HttpClient>(
    () => new HttpClient("https://instagram"),
    container);

container.RegisterConditional(typeof(HttpClient), httpClientInstagramRegistration,
    c => c.Consumer.ImplementationType == typeof(InstagramBusiness));

我很好奇我是否可以完全通过设计来解决这个问题

通过将HttpClient 注入TwitterBusiness 类,您会得到错误的灵活性。您似乎可以进行两种交换实现,但由于 HttpClient 是一种具体类型,因此更改实现毫无意义。由于TwitterBusiness 直接与HttpClient 通信,因此应该将其作为实现细节。换句话说,将HttpClient 的创建移动到TwitterBusiness 中。您需要配置的任何参数(可能是 url)都可以注入TwitterBusiness。这样TwitterBusiness 就可以完全控制HttpClient 的创建和处置,并且您注入唯一感兴趣的内容(网址)。

【讨论】:

谢谢史蒂文。我忘了提到所有的 HttpClient 实例都是单例的,所以 Twitter HttpClient 实例将在应用程序的生命周期中重复使用。我总是倾向于避免使用静态变量,但我想我可以将它作为 TwitterBusiness 中的静态变量,并且如果它在构造函数中为空,则只初始化一次。你怎么看?对于单元测试,我可以将 HttpMessageHandler 传递给构造函数。 @raRaRa 你甚至可以将你的 TwitterBusiness 注册为单例,以防它是无状态的(它通常应该这样做)。这意味着您的 httpclient 仍然可以是实例变量,但我不认为 HttpClient 是线程安全的。所以在每个 mrthod 中创建它是最安全的。 它是线程安全的,应该尽可能地重复使用。这就是为什么我希望它是单例的。否则我只会在 TwitterBusiness 中按需创建 HttpClient 实例。但你绝对是对的,TwitterBusiness 可以注册为单例。我会考虑清楚并尝试做出决定。谢谢您的帮助! :) 似乎单身最好:aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong

asp.netcore依赖注入高级玩法——如何注入多个服务实现类(代码片段)

...将其定义为静态(static),而有了依赖注入,你就要避免使用静态类型,应该交由服务容器帮你管理,只要你用好了, 查看详情

如何将 RateLimiter 的 HttpClient DelegatingHandler 与依赖注入一起使用?

】如何将RateLimiter的HttpClientDelegatingHandler与依赖注入一起使用?【英文标题】:HowcanIuseRateLimiter\'sHttpClientDelegatingHandlerwithdependencyinjection?【发布时间】:2021-05-1722:12:12【问题描述】:我已经在我的项目中成功使用RateLimiter(github)有... 查看详情

使用特定的 HttpMessageHandler 注入单实例 HttpClient

】使用特定的HttpMessageHandler注入单实例HttpClient【英文标题】:InjectingSingleInstanceHttpClientwithspecificHttpMessageHandler【发布时间】:2017-03-3013:09:37【问题描述】:作为我正在处理的ASP.NetCore项目的一部分,我需要从我的WebApi中与许多不... 查看详情

当 API 关闭时,Xamarin 表单依赖注入 HttpClient 超时不起作用

】当API关闭时,Xamarin表单依赖注入HttpClient超时不起作用【英文标题】:XamarinFormsDependenyInjectedHttpClientTimeoutnotworkingwhenAPIisdown【发布时间】:2021-10-0316:36:15【问题描述】:经过一些研究,我了解到为每个请求创建新的HttpClients对Ht... 查看详情

容器外的bean使用依赖注入(代码片段)

...tory是在BeanFactory的基础上实现对已存在实例的管理。可以使用这个接口集成其他框架,捆绑并填充并不由Spring管理生命周期并已存在的实例。ApplicationContext接口没有实现AutowireCapableBeanFactory接口,因为应用代码很少用到此功能,... 查看详情

spring依赖注入

...反转含义相同,它们是从两个角度描述同一个概念。使用依赖注入可以更轻松的管理和测试应用程序。当某个Java实例需要另一个Java实例时,传统的方法是由调用者创建被调用者的实例 查看详情

spring依赖注入

...反转含义相同,它们是从两个角度描述同一个概念。使用依赖注入可以更轻松的管理和测试应用程序。当某个Java实例需要另一个Java实例时,传统的方法是由调用者创建被调用者的实例 查看详情

Sonata 管理控制器 + 依赖注入

...管理和依赖注入而苦苦挣扎。我定义了一个Admin类并为它使用了一个扩展CRUDController的控制器。在这个控制器中我必须做一个HTTP请求,所以我想注入一个ZendHTTP客户端实例。news.controller:clas 查看详情

当我在 HttpInterceptor 类中注入使用 HttpClient 的服务时,Angular 6 进入循环依赖的无限循环

】当我在HttpInterceptor类中注入使用HttpClient的服务时,Angular6进入循环依赖的无限循环【英文标题】:Angular6entersinfiniteloopofcyclicdependencywhenIinjectaservicethatusesHttpClientinsidemyHttpInterceptorclass【发布时间】:2018-12-1023:54:38【问题描述】... 查看详情

依赖注入:HttpClient 还是 HttpClientFactory?

】依赖注入:HttpClient还是HttpClientFactory?【英文标题】:Dependencyinjection:HttpClientorHttpClientFactory?【发布时间】:2019-12-1106:44:17【问题描述】:我到处都可以看到在DI中创建客户端(基本、命名、键入)的三种主要方法,但我找不... 查看详情

asp.netcore依赖注入高级玩法——如何注入多个服务实现类

原文地址:https://www.bbsmax.com/A/nAJvbK0nJr/ 依赖注入在ASP.NETCore中起中很重要的作用,也是一种高大上的编程思想,它的总体原则就是:俺要啥,你就给俺送啥过来。服务类型的实例转由容器自动管理,无需我们在代码中显式处... 查看详情

springmvc在线教程

...vaConfig实例SpringJavaConfig@Import实例Spring依赖注入(DI)Spring使用Setter依赖注入Spring通过构造方法依赖注入SpringBean引用例子如何注入值到Springbean属性Springbean加载多个配置文件Spring内部bean实例SpringBean作用域实例S 查看详情

依赖注入生命周期

...容器释放的时候,会释放由其创建的对象实例。推荐使用容器来来管理我们的对象的创建和释放。操作为了演示,我们创建一个UserService,并让该Service继承IDisposablepublic class UserService : IUserService, IDisposable    publi... 查看详情

androiddagger-hilt依赖注入(代码片段)

...HiltAndroidApp将依赖项注入Android类@Inject注入定义Hilt绑定使用@Binds注入接口实例使用@Provides注入实例为同一类型提供多个绑定,使用限定符@Qualifier预定义限定符:@ApplicationContext,@ActivityContextHilt组件组... 查看详情

spring中依赖注入常见方式比较

...1.违反了单一原则当一个class中有多个依赖时,如果仅仅使用Field注入,则看不出有很多依赖关系。而使用构造注入setter 注入,可以观察到,这样我通常会对代码进行重构。2.依赖隐藏使用DI容器,类本身不再管理其依赖,但... 查看详情

如何使用手动依赖注入实例化一个类?(代码片段)

我有一个可能需要服务的类,以前通过依赖注入注册,具体取决于用户需求。他通过静态方法GetInstance(bool)实现我的类,如果bool设置为true,那么我需要根据依赖注入调用构造函数。怎么做到这一点?publicclassMyClassprivateMyClass()//..... 查看详情

如何使用 Angular 中的依赖注入将属性指令实例传递给嵌套组件

】如何使用Angular中的依赖注入将属性指令实例传递给嵌套组件【英文标题】:HowtopassattributeDirectiveinstancetonestedcomponentusingDependencyInjectioninAngular【发布时间】:2020-11-1422:10:34【问题描述】:我正在尝试使用属性指令将元素的模板... 查看详情

可重用的 HttpClient 实例与静态变量(在多个线程中大量使用)?

】可重用的HttpClient实例与静态变量(在多个线程中大量使用)?【英文标题】:ReusableHttpClientinstancevsstaticvariable(Heavilyusedinmultiplethreads)?【发布时间】:2017-10-2518:47:28【问题描述】:我目前有一个HttpClient的实例变量,它在实例方... 查看详情