Scala Guice 中的依赖注入——传递参数

Dependency Injection in Scala Guice - Passing Parameters

我有一个非常简单的场景可以使用 DI 来解决,但我找不到合适的 example/documentation 来解决问题。我是 Scala/Guice 世界的新手。

当前组件如下所示

trait Foo {
}

class FooImpl extends A {

}

trait Bar {
   val description: String
}

class BarImpl(val description: String) extends Bar {

}

现在,我在 Foo 和 Bar 之间建立了依赖关系。 所以,通常代码看起来像这样

class FooImpl extends Foo {
  Bar bar = createBar("Random Bar Value!")
}

其中 createBar("Bar!") 只是 returns new BarImpl("Random Bar Value")。当然,为了简洁起见,我删除了 factory/helper。

我意识到,当我使用 "new" 时,这超出了 DI 范式。我想确保可以根据参数将 Bar 注入到 FooImpl 中。有点像使用工厂。我们如何在 Scala/Guice 世界中使用 DI。

我查看了 AssistedInjection/Named 参数,但我无法理解最终的用法。我认为这是最好的方法,但不明白它应该如何 written/tested。

好的,这终于对我有用了。为任何想要处理基于 Scala 的辅助注射的人重写这些步骤。

Foo 可能需要 Bar,但真正需要注入的是 BarFactory,而不是 Bar。

需要创建一个BarFactory,但实现可以留给Guice。这就是它变得棘手的地方。

trait BarFactory {
  def create(msg:String):Bar
}

那么让我们重温一下 Foo 和 Bar:

@ImplementedBy(classOf[FooImpl])
trait Foo {
  def getBar(msg: String): Bar
}

class FooImpl @Inject() (barFactory: BarFactory) extends Foo {
  override def getBar(msg: String): Bar = {
    barFactory.create(msg)
  }
}

@ImplementedBy(classOf[BarImpl])
trait Bar {
  def echo() : String
}

//Note that we use the @Assisted Annotation Here.
class BarImpl @Inject() (@Assisted msg: String) extends Bar {
  override def echo(): String = msg
}

创建实际工厂是作为模块的一部分完成的

class TempModule extends AbstractModule {
  override def configure(): Unit = {
    install(new FactoryModuleBuilder()
      .implement(classOf[Bar], classOf[BarImpl])
      .build(classOf[BarFactory]))
  }
}

并且一旦开始,工厂实现将由 Guice 提供,您应该能够使用工厂创建您的实际实现。