代码之家  ›  专栏  ›  技术社区  ›  BC.

依赖注入框架是否值得额外的间接层?

  •  11
  • BC.  · 技术社区  · 15 年前

    您是否发现依赖注入框架使代码更难遵循?间接利益大于利益吗?

    9 回复  |  直到 13 年前
        1
  •  13
  •   ocodo    13 年前

    是的,您的代码变得更加不耦合和可测试。当您有很多测试并且每个测试都需要一个像数据库层这样的重对象时,这一点特别有用。

    如果您使用依赖注入,您可以简单地创建所谓的“模拟”对象或存根,并使用这些对象让您的测试运行得更快,副作用更少(数据库状态)。

    确实,您无法通过查看代码直接看到使用了哪个实现。您将看到对接口的引用。一个好的IDE可能具有查看特定接口的所有实现的功能,因此使用它是为了您的利益。

        2
  •  5
  •   jcrossley3    15 年前

    对于非平凡的“企业”应用程序来说,是的,它是值得的。在DI框架之前,每个商店都实现了自己的想法 “服务定位器” 在其他项目使用的某个内部库中初始化。所以你在整个代码库中都有对那个东西的调用。

    这些调用表示对象需要发现/配置自己的依赖项。DI框架消除了所有这些代码,因此您的对象变得更简单,因此更容易测试。

    现在,如果您的对象依赖性中没有太多的可变性,那么间接(集中配置)的值对您来说就更少了。

    有关将DI与服务定位器进行对比的更多详细信息,请参阅Fowler's Inversion of Control Containers and the Dependency Injection pattern

        3
  •  5
  •   Pita.O    15 年前

    我发现一个定制的静态哈希表工厂可以很好地分离我的依赖关系并满足我的需求。我试过几次使用一个完整的IOC容器,每次我被学习曲线(和所有的配置)吓到,我的团队中的其他人必须忍受…所有这些都是为了在我的香草味基础上增加一些或不增加一些特色。

    因此,我猜依赖注入的更大问题不在模式本身,而是在开发人员社区中它当前生成的fad中。这听起来很酷,所以使用它是有压力的,即使工程不是由一个相称的要求驱动的。

    我们倾向于用一把大枪对着蚊子,因为这把枪看起来很酷。

        4
  •  3
  •   Dan    15 年前

    DI的好处很难一眼就领会。可测试性是最明显的。我试着用一个很短的例子来说明这些好处。假设您的应用程序正在使用某个数据库提供程序。如果您让所有的代码只看到DB提供程序接口,您将很容易地从一个实现切换到另一个实现。现在,如果您制作企业应用程序,而不是依赖于特定的数据库提供者,可能是非常理想的,就像客户机已经购买了数据库许可证一样。这实际上得益于依赖接口而不是实现。到现在为止,一直都还不错。 现在,我需要以某种方式抓住我的具体对象。我的具体对象只能是具体提供者的实例。我该怎么做?

    1. 使用“新建”创建对象。
      我会的 必须在中重新编译项目 命令分发它。巨大的 缺点:必须测试、部署, 维护新的代码分支等。
    2. 使用工厂。
      我的密码会撒上 拥有工厂代码 并获取实例。另外,我 必须返回一个泛型 实例并将其强制转换为 我期待的对象。如果没有,我就要 更改工厂界面 添加新对象的时间 工厂。
    3. 使用服务定位器。
      相似的 为2。仅限,取决于服务 定位器可能并不总是在附近, 像JavaJNDI一样。

    DI将其外部化,并采用注入是单独关注的方法。您的对象应该关注域,而不是寻找合适的合作者。

        5
  •  2
  •   Jeffrey Cameron    15 年前

    最初我喜欢依赖注入框架的想法,但是除了支持单元测试之外,我仍然不相信使用它的好处。对于接管我项目的人来说,这意味着还有一个框架/api/技术需要学习,而且在某些情况下可能更详细。在这两篇相互竞争的博客文章中,你可以发现一个非常好的前后对比。

    For DI Framework

    Against DI Framework

    底线是这样的 真的? 减少耦合,增加内聚力,或者只是把问题推到表面之下。在我现在的项目中,我看不到对它的太多需求,甚至不需要支持单元测试。不过,如果你想为C买一个,我强烈推荐Ninject。它重量轻,简单,配置完全流畅…没有XML!糖果:)

        6
  •  1
  •   ollifant    15 年前

    在我看来,依赖注入框架不会使代码更复杂。事实上,您只看到对接口的引用,而不是对具体实现的引用,这是很好的——因为您不必关心具体实现是如何工作的。

    如果在源代码中导航太困难,请获取Resharper,一切正常。

        7
  •  1
  •   oxbow_lakes    15 年前

    依赖注入是一个奇妙的想法;尽管 实际上,您可以纯粹地对接口进行编码。它强制(或鼓励)您将程序中的关注点分离为多个不知道的协作服务类型实例。 怎样 相互实现。这样就不太可能在类之间引入不需要的和不必要的依赖项。

    然而,控制反转并不是唯一的方法。一位同事通过编写自己的 JNDI . 花了很长时间才赢得我的支持,但这是非常棒的,它的配置与典型的 Spring 项目。

        8
  •  1
  •   Nicholas Piasecki    15 年前

    您可以设计类来注入它们的依赖项(通过构造函数或属性),而不必使用依赖项注入框架。只需自己实例化依赖项,并将其传入或从一起抛出的服务定位器或注册表类中获取。但是,不要让类本身通过调用服务定位器来解析其依赖项,而是让正在实例化类的类解析其依赖项。您维护一个可测试的类设计,而不需要另一个库和框架的开销和复杂性。

    我个人知道,每当我尝试使用DI框架时,这基本上就是我最终真正使用它的目的。我也看到过这样的情况:人们将自己的DI容器包装在一个静态IOC类中,以便在层次结构中构建向下的对象,在我看来,这种做法破坏了目标;难道这不是刚刚回到服务定位器的位置吗?我想我在实际使用上还不太明白。我说的是恶作剧,你在用反省和一个大的初创公司来做同样的事情。

    您不能消除依赖项,但是您确实可以在XML配置文件中混淆它们。在某一时刻 某物 会打电话给 new . 您是否真的要在不重新编译或重新测试应用程序的情况下交换接口的实现?如果没有,保持简单。单击“find definition”并看到在服务定位器类中用显式的singleton或 ThreadStatic 或者其他一些行为。

    只是我的两分钱——我对DI框架还很陌生,但这是我目前的思路:控制反转是有用的,但实际框架本身可能只适用于非常大的项目。

        9
  •  0
  •   CodingWithSpike    15 年前

    我认为好处取决于你如何使用它。

    例如,在我当前的项目中,我们使用dep inj根据应用程序配置(特别是单元测试)注入不同的项。一个很好的例子是让一个生产系统使用真正的“登录”实现,但是让单元测试使用一个模拟的“登录”,它总是为一个已知的登录返回true/valid,但没有其他的。