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

时间:2016-11-20 13:27:54

标签: c# dependency-injection dotnet-httpclient simple-injector ambiguous

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

我想使用依赖注入和SimpleInjectorHttpClient注入业务类。例如,我有ITwitterBusinessIInstagramBusiness,并且他们都在构造函数中接受HttpClient

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

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

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

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

看起来很简单,但我不知道这种方法是否有任何不良副作用,例如让SimpleInjector运行得更慢或者我打破了一些设计模式。

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

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

如果我能够纯粹通过设计解决这个问题,我很好奇。例如,通过创建虚拟类。我还没有找到任何好的例子,但是如果我理解正确的话,那么我可以创建继承HttpClientTwitter的虚拟类,例如HttpClient,这样我就可以摆脱模糊的注册

谢谢!

1 个答案:

答案 0 :(得分:3)

  

我的第一个想法是在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的创建和处理,并且只注入唯一有趣的内容(网址)。