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

时间:2016-09-07 10:57:02

标签: scala dependency-injection guice

我有一个非常简单的方案来解决使用DI,但我无法找到一个合适的示例/文档来帮助我完成。我是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!")只返回new BarImpl("Random Bar Value")。当然,为了简洁,我正在拆除工厂/助手。

我意识到,在我使用“新”的那一刻,这已经超出了DI范式。我想确保可以根据参数将Bar注入FooImpl。有点像使用工厂。我们如何在Scala / Guice世界中使用DI。

我看了一下AssistedInjection / Named Parameters,但我无法理解使用情况会如何。我认为这是最好的方法,但无法理解应如何编写/测试。

1 个答案:

答案 0 :(得分:0)

好的,所以这最终对我有用。为任何想要处理Scala Based Assisted Injection的人重写这些步骤。

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提供,您应该能够使用工厂创建实际的实现。