使用依赖注入管理 HttpClient 的多个实例
Managing multiple instances of HttpClient using Dependency Injection
我正在为我的 Web 应用程序与之通信的每个不同 API 创建一个 HttpClient
实例。
我想使用 SimpleInjector 的依赖注入将 HttpClient
注入业务 classes。例如,我有 ITwitterBusiness
和 IInstagramBusiness
,它们都在构造函数中接受 HttpClient
。
使用依赖注入注册多个相同类型的对象时,最佳实践是什么?
我很确定部分问题可能出在我的设计上,但这里有一些想法。
我的第一个想法是在DI注册中使用delegate
container.Register<ITwitterBusiness>(() => new TwitterBusiness(httpClientTwitter));
看起来很简单,但我不知道这种方法是否有任何不良副作用,例如使 SimpleInjector 运行 变慢或者我是否破坏了某些设计模式。
我的第二个想法是使用基于上下文的注入 http://simpleinjector.readthedocs.io/en/latest/advanced.html#context-based-injection
我相信这将允许我将某个 HttpClient 实例注入某个 class。仍然不确定这是如何工作的。
我很好奇我是否可以纯粹通过设计来解决这个问题。例如通过创建虚拟 classes。我只是没有找到任何好的例子,但如果我理解正确,那么我可以创建虚拟 classes,例如继承 HttpClient
的 HttpClientTwitter
,这样我就可以摆脱不明确的注册。
谢谢!
My first idea is to use delegate in the DI registration. Seems simple enough, but I don't know if this method has any bad side effects, for example by making SimpleInjector run slower or if I'm breaking some design pattern.
如果类型有任何需要连接的应用程序组件,建议使用自动连接(与注册委托相反)。自动装配简化了注册并允许简单注入器分析对象图。两者似乎都与您的情况无关。 HttpClient
不是应用程序组件,而是基础结构类型。似乎没有其他依赖项,因此注册委托不会造成任何可维护性问题。
与使用自动装配相比,委托注册速度较慢,Simple Injector 无法使用委托进行优化。然而,在执行此操作时,非常 不太可能注意到任何性能差异。这不是你应该担心的事情。
My second idea is to use Context based injection. I believe this will allow me to inject a certain HttpClient instance to a certain class. Still not exactly sure how this works.
您可以根据上下文进行不同的注册。例如:
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));
I'm very curious if I could solve this purely by design
通过将 HttpClient
注入到 TwitterBusiness
class 中,您会产生一种错误的灵活性感。您似乎可以实现两个交换实现,但由于 HttpClient
是具体类型,因此更改实现没有任何意义。由于 TwitterBusiness
直接与 HttpClient
通信,这应该是一个实现细节。换句话说,将 HttpClient
的创建移动到 TwitterBusiness
中。您需要配置的任何参数(可能是 url)都可以注入到 TwitterBusiness
中。这样 TwitterBusiness
就可以完全控制 HttpClient
的创建和处置,并且您可以注入唯一需要更改的东西(url)。
我正在为我的 Web 应用程序与之通信的每个不同 API 创建一个 HttpClient
实例。
我想使用 SimpleInjector 的依赖注入将 HttpClient
注入业务 classes。例如,我有 ITwitterBusiness
和 IInstagramBusiness
,它们都在构造函数中接受 HttpClient
。
使用依赖注入注册多个相同类型的对象时,最佳实践是什么?
我很确定部分问题可能出在我的设计上,但这里有一些想法。
我的第一个想法是在DI注册中使用delegate
container.Register<ITwitterBusiness>(() => new TwitterBusiness(httpClientTwitter));
看起来很简单,但我不知道这种方法是否有任何不良副作用,例如使 SimpleInjector 运行 变慢或者我是否破坏了某些设计模式。
我的第二个想法是使用基于上下文的注入 http://simpleinjector.readthedocs.io/en/latest/advanced.html#context-based-injection
我相信这将允许我将某个 HttpClient 实例注入某个 class。仍然不确定这是如何工作的。
我很好奇我是否可以纯粹通过设计来解决这个问题。例如通过创建虚拟 classes。我只是没有找到任何好的例子,但如果我理解正确,那么我可以创建虚拟 classes,例如继承 HttpClient
的 HttpClientTwitter
,这样我就可以摆脱不明确的注册。
谢谢!
My first idea is to use delegate in the DI registration. Seems simple enough, but I don't know if this method has any bad side effects, for example by making SimpleInjector run slower or if I'm breaking some design pattern.
如果类型有任何需要连接的应用程序组件,建议使用自动连接(与注册委托相反)。自动装配简化了注册并允许简单注入器分析对象图。两者似乎都与您的情况无关。 HttpClient
不是应用程序组件,而是基础结构类型。似乎没有其他依赖项,因此注册委托不会造成任何可维护性问题。
与使用自动装配相比,委托注册速度较慢,Simple Injector 无法使用委托进行优化。然而,在执行此操作时,非常 不太可能注意到任何性能差异。这不是你应该担心的事情。
My second idea is to use Context based injection. I believe this will allow me to inject a certain HttpClient instance to a certain class. Still not exactly sure how this works.
您可以根据上下文进行不同的注册。例如:
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));
I'm very curious if I could solve this purely by design
通过将 HttpClient
注入到 TwitterBusiness
class 中,您会产生一种错误的灵活性感。您似乎可以实现两个交换实现,但由于 HttpClient
是具体类型,因此更改实现没有任何意义。由于 TwitterBusiness
直接与 HttpClient
通信,这应该是一个实现细节。换句话说,将 HttpClient
的创建移动到 TwitterBusiness
中。您需要配置的任何参数(可能是 url)都可以注入到 TwitterBusiness
中。这样 TwitterBusiness
就可以完全控制 HttpClient
的创建和处置,并且您可以注入唯一需要更改的东西(url)。