除了可测性之外,利用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(...)
方法。
答案 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次。这是我记得的一个这样的讨论(按顺序阅读):
关于您的特定问题,似乎您没有正确管理您的服务生活方式......例如,如果您的某项服务是有状态的(这应该是非常罕见的),它可能必须是暂时的。我建议您根据需要创建尽可能多的SO问题,以便消除所有疑虑。
答案 3 :(得分:0)
有Guice video为使用D.I.提供了一个很好的示例。如果您正在使用许多需要动态连接的第三方服务,那将是一个很好的帮助。