没有Play框架的Scala中如何使用依赖注入?

时间:2019-04-05 13:10:27

标签: scala dependency-injection

我有使用Scala和Play开发基于Web的应用程序的经验。 Play支持开箱即用的Guice,因此使用Play进行DI很容易。

我目前正在研究不是Web应用程序且不使用Play的Scala项目。我想动态地将config对象注入几个地方。我该怎么做?

如果有必要使用某些库来进行DI,那么哪个库对此有用呢?任何示例代码?是否可以通过不使用任何外部库的纯Scala实现此目的?当我在“没有播放的Scala DI”上进行搜索时,所有结果都与播放有关。

谢谢!

3 个答案:

答案 0 :(得分:2)

播放与依赖项注入无关。由Guice-广泛的Java DI库处理。

要掌握Guice的主要概念,我建议您阅读this source

答案 1 :(得分:1)

我喜欢使用Macwire

设置

将此行添加到您的build.sbt文件中:

libraryDependencies += "com.softwaremill.macwire" %% "macros" % "2.3.2" % Provided

然后重新加载。
注意,作用域为Provided,因此它不会增加任何运行时开销。它使用宏在编译时完成其工作。这意味着您将获得编译时依赖项注入,如果缺少依赖项,则会尽快发现它-出现编译时错误,而不是运行时异常。

代码示例

  • 让我们定义两个服务X和Y,它们具有一些依赖性A,B和C,因此我们以后可以使用它们:
case class A()
case class B()
case class C()
case class X(a: A, b: B)
case class Y(c: C)
  • 现在让我们在世界的尽头(在main函数附近)连接我们的依赖项:
import com.softwaremill.macwire._

lazy val a = wire[A]
lazy val b = wire[B]
lazy val c = wire[C]
lazy val x = wire[X]
lazy val y = wire[Y]
  • 编译器会将上面的代码转换为以下代码:
lazy val a = new A()
lazy val b = new B()
lazy val c = new C()
lazy val x = new X(a, b)
lazy val y = new Y(c)

正如您在帖子中所问的那样,这基本上是使用纯Scala代码的实现。

更改依赖项

这里的一件好事是,当其中一项服务通过添加/删除依赖项进行更改时,您的接线代码将保持不变。
例如,让我们将服务Y更改为也要求B作为依赖项。

  • 我们的服务和依赖项将如下所示:
case class A()
case class B()
case class C()
case class X(a: A, b: B)
case class Y(b: B, c: C)
  • 接线代码将保持不变。

  • 编译器会将接线代码转换为:

lazy val a = new A()
lazy val b = new B()
lazy val c = new C()
lazy val x = new X(a, b)
lazy val y = new Y(b, c)

答案 2 :(得分:0)

我不确定,但是我认为您仍然可以使用

"com.google.inject" % "guice" % "4.2.2"

并实现类似这样的东西。

class Module extends com.google.inject.AbstractModule {
  protected def configure() = {
    // Example Usage:
    bind(classOf[ClassNameToInjected]).asEagerSingleton()
  }
}

希望这会有所帮助。