您是否发现依赖注入框架使代码更难以遵循?间接是否超过了利益?
答案 0 :(得分:13)
是的,您的代码变得更加分离并且更加可测试。当您进行大量测试并且每个测试需要一个繁重的对象(如数据库层)时,这尤其会变得很方便。
如果你使用依赖注入,你可以简单地创建所谓的'mock'对象或存根,并使用它们让你的测试运行得更快,副作用更少(数据库状态)。
通过查看代码,您无法直接看到使用的实现。您将看到对该界面的引用。一个好的IDE可能具有查看特定接口的所有实现的功能,因此请使用它。
答案 1 :(得分:5)
对于非平凡的“企业”应用程序,是的,这是值得的。在DI框架之前,每个商店都在其他项目使用的某个内部库中实现了自己的花式“ServiceLocator”类。因此,您可以在整个代码库中调用那些东西。
这些调用表示对象需要发现/配置自己的依赖项。 DI框架消除了所有代码,因此您的对象变得更简单,因此更容易测试。
现在,如果您的对象的依赖关系中没有很多可变性,那么间接值(集中式配置)对您来说就不那么重要了。
有关将DI与ServiceLocator对比的更多详细信息,请参阅Fowler的Inversion of Control Containers and the Dependency Injection pattern
答案 2 :(得分:5)
我发现自定义静态HashTable工厂可以很好地解耦我的依赖项并满足我的需求。我已经尝试了几次使用一个完整的IOC容器,每次我对我的团队其他成员必须忍受的学习曲线(以及所有配置)感到吃惊......以及所有这些或者我的香草没有添加任何功能。
所以,我认为依赖注入的更大问题不在于模式本身,而在于它目前在开发人员社区中生成的Fad。这听起来很酷,因此使用它的压力很大,即使工程不是由相应的要求驱动的。
我们倾向于用大枪给蚊子看枪,因为枪看起来很酷。
P
答案 3 :(得分:3)
一开始就很难掌握DI的好处。可测试性是最明显的。我将尝试用一个很短的例子来说明这些好处。想象一下您的应用程序正在使用某个数据库提供程如果保持所有代码只看到数据库提供程序接口,则可以轻松地从一个实现切换到另一个实现。现在,如果您制作企业应用程序,不依赖于特定的数据库提供程序可能是非常可取的,就像客户端已经购买了DB许可证一样。这实际上是取决于接口而不是实现的好处。到现在为止还挺好。 现在,我需要以某种方式抓住我的具体对象。我的具体对象只能是具体提供者的实例。我该怎么做?
DI将此外化,并采取注入单独关注的方法。您的对象应该关注域,而不是寻找合适的协作者。
答案 4 :(得分:2)
我最初喜欢依赖注入框架的想法,但除了支持单元测试之外,我仍然不相信使用它的好处。对于接管我的项目学习的人来说,这意味着还有一个框架/ API /技术,在某些情况下实际上可能更冗长。您可以在这两个相互竞争的博客条目中找到关于优缺点的优秀来回
底线归结为真的减少耦合并增加内聚力,还是只是推动表面下的问题。在我的项目中,即使支持单元测试,我也认为不太需要它。如果您打算为C#选择一个,我强烈推荐Ninject。它轻巧,简单,完全流畅配置......没有XML! Sweeet:)
答案 5 :(得分:1)
在我看来,依赖注入框架不会使代码更复杂。您只看到对接口的引用而不是对具体实现的引用这一事实很好 - 因为您不必关心具体实现的工作方式。
如果浏览源代码太难了,请使用Resharper,一切都很好。
答案 6 :(得分:1)
依赖注入是一个很棒的主意;虽然 win 的很大一部分在于你可以纯粹编写接口代码。它强制(或鼓励)您将程序中的问题分成多个协作服务类型的实例,这些实例不知道 彼此是如何实现的。这使得您不太可能在类之间引入不需要的和不必要的依赖关系。
但是,控制倒置不是唯一的方法。一位同事通过编写自己的JNDI
实现来实现这一目标。我花了很长时间才赢得了我,但它很棒,而且只有一小部分典型Spring项目的配置。
答案 7 :(得分:1)
您可以设计类以使其依赖项注入(通过构造函数或属性),而无需使用依赖项注入框架。只需自己实例化依赖项并将其传递或从您抛出的服务定位器或注册表类中获取它。但是,不要让类本身通过调用服务定位器来解析其依赖关系,而是让实例化类的类解析它的依赖关系。您维护一个可测试的类设计,而没有另一个库和框架的开销和复杂性。
我知道每当我尝试使用DI框架时,基本上就是我真正最终使用它的所有内容。我还看到过人们将他们的DI容器包装在静态IoC类中以在层次结构中构建对象的情况,在我看来这种方法会失败的目的;是不是就在那时成为服务定位器?我想我在实际使用中并没有太大的区别。我说恶作剧,你正在使用反思并采取重大启动来做同样的事情。
您无法消除依赖关系,但您确定可以在XML配置文件中混淆它们。在某些时候某事将调用new
。您是否真的要更换接口的实现而无需重新编译或重新测试您的应用程序?如果没有,请保持简单。很高兴单击“查找定义”并查看实际在服务定位器类中实例化的内容,其中包含显式单例或ThreadStatic
或其他一些行为。
只是我的两分钱 - 我仍然是DI框架的新手,但这是我目前的思路:控制反转很有用,但实际的框架本身可能只适用于非常大的项目。
答案 8 :(得分:0)
我认为好处取决于你如何使用它。
例如,在我当前的项目中,我们使用dep inj来根据应用程序配置注入不同的项目,特别是单元测试。一个很好的例子就是让一个生产系统使用一个真正的“登录”实现,但让单元测试使用一个模拟“登录”,它总是对知道登录返回true / valid,但没有其他人。