除了测试之外,依赖注入如何比静态类/方法更好?

时间:2009-09-27 04:50:15

标签: c# architecture static dependency-injection

除了可测性之外,利用D.I.的最大优势是什么? (而我不是在谈论D.I.框架或IoC)而不是静态类?特别是对于您不知道服务不会被换出的应用程序。

在我们的一个c#应用程序中,我们的团队正在Web Web GUI,服务层和存储库层中使用依赖注入,而不是使用静态方法。在过去,我们有POCO(业务实体对象),它们是由静态类创建,修改,传递和保存的。

例如,过去我们可能写过:

CreditEntity creditObj = CreditEntityManager.GetCredit(customerId);
Decimal creditScore = CreditEntityManager.CalculateScore(creditObj);
return creditScore;

现在,使用D.I.,相同的代码将是:

//not shown, _creditService instantiation/injection in c-tors
CreditEntity creditObj = _creditService.GetCredit(customerId);
Decimal creditScore = _creditService.CalculateScore(creditObj);
return creditScore;

没有太大区别,但是现在我们有几十个具有更广泛范围的服务类,这意味着我们应该将它们视为静态(即没有私有成员变量,除非它们用于定义更多依赖项)。另外,如果这些方法中的任何一种利用资源(数据库/ Web服务/等),我们会发现管理并发问题更加困难,除非我们删除依赖项并使用旧的静态或using(...)方法。

4 个答案:

答案 0 :(得分:5)

D.I.的问题可能是:CreditEntityManager实际上是集中了解如何查找CreditEntity以及去往CalculateScore的地方的知识的自然场所吗?

我认为D.I.的理论是事件 X 中涉及的模块化应用程序不一定知道如何连接事物 Y ,即使 X 需要 Y

在您的示例中,您将在找到服务提供程序并将其合并到数据对象后显示代码流。在这一点上,确定,有和没有D.I.它看起来大致相同,甚至可能完全相同,具体取决于编程语言,风格等。

关键是如何将这些不同的服务连接在一起。在D.I.中,潜在的第三方对象本质上是进行配置管理,但在此之后,代码应该大致相同。 D.I.的观点不是要改进以后的代码,而是尝试将问题的模块化特性与程序的模块化特性相匹配,以避免编辑逻辑上正确的模块和程序逻辑,但却与错误的服务挂钩提供者。

答案 1 :(得分:1)

它允许您在不破解代码的情况下交换实现。例如,在我的一个应用程序中,我们创建了一个名为IDataService的接口,该接口定义了查询数据源的方法。对于前几个生产版本,我们使用了使用nHibernate的Oracle实现。后来,我们想切换到一个对象数据库,所以我们为db4o编写和实现,将其程序集添加到执行目录并更改了配置文件中的一行。普雷斯托!我们使用db4o而不必破解代码。

答案 2 :(得分:1)

这已被讨论了1002次。这是我记得的一个这样的讨论(按顺序阅读):

  1. http://scruffylookingcatherder.com/archive/2007/08/07/dependency-injection.aspx
  2. http://ayende.com/Blog/archive/2007/08/18/Dependency-Injection-More-than-a-testing-seam.aspx
  3. http://kohari.org/2007/08/15/defending-dependency-injection
  4. http://scruffylookingcatherder.com/archive/2007/08/16/tilting-at-windmills.aspx
  5. http://ayende.com/Blog/archive/2007/08/18/Dependency-Injection-IAmDonQuixote.aspx
  6. http://scruffylookingcatherder.com/archive/2007/08/20/poking-bears.aspx
  7. http://ayende.com/Blog/archive/2007/08/21/Dependency-Injection-Applicability-Benefits-and-Mocking.aspx
  8. 关于您的特定问题,似乎您没有正确管理您的服务生活方式......例如,如果您的某项服务是有状态的(这应该是非常罕见的),它可能必须是暂时的。我建议您根据需要创建尽可能多的SO问题,以便消除所有疑虑。

答案 3 :(得分:0)

Guice video为使用D.I.提供了一个很好的示例。如果您正在使用许多需要动态连接的第三方服务,那将是一个很好的帮助。