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

Managing multiple instances of HttpClient using Dependency Injection

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

我想使用 SimpleInjector 的依赖注入将 HttpClient 注入业务 classes。例如,我有 ITwitterBusinessIInstagramBusiness,它们都在构造函数中接受 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,例如继承 HttpClientHttpClientTwitter,这样我就可以摆脱不明确的注册。

谢谢!

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)。