【问题标题】:How would one do dependency injection in scala?如何在 scala 中进行依赖注入?
【发布时间】:2010-04-01 21:51:36
【问题描述】:

除了java之外,我还在学习scala的开始,我不明白应该如何在那里做DI?我可以或应该使用现有的 DI 库,应该手动完成还是有其他方法?

【问题讨论】:

标签: scala dependency-injection


【解决方案1】:

标准 Java DI 框架通常可以与 Scala 一起使用,但您也可以使用语言构造 achieve the same effect 而无需外部依赖。

【讨论】:

  • 该链接通过许多示例为我提供了一个非常好的概述。非常感谢。
  • fwiw,那篇文章是我刚开始学习 Scala 时最强烈的灵感之一。
  • 我很好奇当服务或注册表可能需要不同数量的组件实例时,蛋糕模式是如何实现的。例如,如果链接示例中的 WarmerComponentImpl 需要两个不同的 OnOffDeviceComponent 实例来完成其工作,该怎么办?
  • @MitchBlevins,查看Dependency Injection in Scala 指南中的“多种实现”部分。
  • 关于如何在 Scala 中进行 DI 的一般概述。看看:blog.knoldus.com/2014/07/04/dependency-injection-scala
【解决方案2】:

Dick Wall 的SubCut 是专门针对 Scala 的新依赖注入库。

Dan Story 的回答中引用的 Jonas Bonér 文章强调编译时绑定实例和静态注入(通过混合),而 SubCut 基于不可变模块的运行时初始化,以及通过按类型查询绑定模块的动态注入,字符串名称,或 scala.Symbol 名称。

您可以在GettingStarted 文档中阅读有关与蛋糕模式比较的更多信息。

【讨论】:

    【解决方案3】:

    依赖注入本身可以在没有任何工具、框架或容器支持的情况下完成。您只需要从代码中删除 news 并将它们移动到构造函数。剩下的一个单调乏味的部分是在“世界尽头”连接对象,容器在这方面有很大帮助。

    尽管使用 Scala 的 2.10 宏,您可以在编译时生成连接代码,并具有自动连接和类型安全性。

    Dependency Injection in Scala Guide

    【讨论】:

    • 很少有人意识到这一点,所以我将其用作面试问题。
    【解决方案4】:

    最近的一个项目展示了一个完全基于构造函数注入的 DI:zalando/grafter

    构造函数注入又出了什么问题?

    在 Scala 中有 many librariesapproaches 用于执行 dependency injection。 Gratter 通过仅使用构造函数注入回到依赖注入的基础:没有反射、没有 xml、没有注释、没有继承或自类型。

    然后,Grafter 将必要的支持添加到构造函数注入:

    • 从配置中实例化基于组件的应用程序
    • 微调布线(创建单例)
    • 通过替换组件来测试应用程序
    • 启动/停止应用程序

    Grafter 瞄准了所有可能的应用程序,因为它只专注于关联 3 个想法:

    • 组件的案例类和接口
    • Reader 实例和无形的配置
    • 其他一切的树重写和 kiama!

    【讨论】:

      【解决方案5】:

      我自己没有这样做,但大多数 DI 框架都在字节码级别 (AFAIK) 工作,因此应该可以将它们与任何 JVM 语言一起使用。

      【讨论】:

      • 过去几年我在 Scala 中成功使用的一个标准 Java DI 框架是 PicoContainer。 (并且您可以使用构造函数注入而不是 setter 注入来保持不变性。)
      • Spring ME 是一个依赖注入框架,它使用源代码分析来实现整个 Spring 在运行时所做的大部分工作。因此,您最终会得到几乎零占用空间的应用程序上下文,而不依赖于任何外部库。不确定我是否会将它用于 Scala。
      【解决方案6】:

      以前的帖子介绍了这些技术。我想添加 Martin Odersky 2014 年 5 月关于 Scala 语言目标的演讲的链接。他认为那些“需要”DI 容器来注入依赖项的语言实现得很差。我个人同意这一点,但这只是一种观点。这似乎表明在您的 Scala 项目中包含 DI 依赖项是非惯用的,但这又是一种观点。实际上,即使使用一种旨在本地注入依赖项的语言,使用容器也可以获得一定程度的一致性。出于您的目的,这两种观点都值得考虑。

      https://youtu.be/ecekSCX3B4Q?t=1154

      【讨论】:

        【解决方案7】:

        我建议你试试distage(免责声明:我是作者)。

        它允许你做的比典型的 DI 做的更多,并且有很多 unique traits

        1. distage 支持多种配置(例如,您可以运行您的应用 具有不同的组件实现集),
        2. disstage 允许您在测试中正确共享依赖项 并轻松运行您的same tests for different implementations 组件,
        3. distage 支持roles,因此您可以在同一进程中运行多个服务,共享它们之间的依赖关系,
        4. distage 不依赖于scala-reflect (但支持 Scala 类型系统的所有必要功能,例如 更高种类的类型)。

        您还可以观看our talk at Functional Scala 2019,我们在其中讨论并展示了一些重要的变态能力。

        【讨论】:

          【解决方案8】:

          我已经展示了如何使用 2.10 here. 在 scala 中创建一个非常简单的功能性 DI 容器

          【讨论】:

            【解决方案9】:

            除了 Dan Story 的回答之外,我还写了一篇关于 DI 变体的博客,该变体也仅使用语言结构,但在 Jonas 的帖子中未提及:Value Injection on Traits(现在链接到 web.archive.org)。 这种模式对我来说效果很好。

            【讨论】:

            • 博客链接失效,能否详细说明
            猜你喜欢
            • 2014-03-25
            • 1970-01-01
            • 2011-08-01
            • 1970-01-01
            • 1970-01-01
            • 2021-10-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多