我有一个非常简单的方案来解决使用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,但我无法理解使用情况会如何。我认为这是最好的方法,但无法理解应如何编写/测试。
答案 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提供,您应该能够使用工厂创建实际的实现。