Guice Assisted Inject with Providers或FactoryModuleBuilder

时间:2017-02-28 04:23:10

标签: scala dependency-injection playframework guice

这是一个奇怪的用例,我需要一些帮助来确定如何将Assisted / Providers / FactoryModuleBuilders相互结合使用。忽略@Singleton的缺席。这只是一个例子。

属于我无法更改的库的一组特征具有以下模式。它使用Cake Pattern。

trait A { //Has abstract methods and abstract service 'webService' }
trait B extends A { //First Concrete Service Implementation assigned to 'webService' }
trait C extends A { //Second Concrete service Implementation assigned to 'webService' }

由于不能直接注入特征,我创建了一个允许注入它们的包装器

BB extends B
CC extends C

在我的代码中,我有一个依赖于服务的控制器,而服务器依赖于库。该服务应该能够使用" BB"或" CC"取决于控制器需要什么。因此组件如下所示

我将我的服务创建为

//Note: Uses 'trait A' with @Assisted
class SomeWebServiceComponent @Inject()(@Assisted aInstance: A, foo: Foo){
    //Do something with aInstance
}

工厂要创建它(应该由Guice使用FactoryModuleBuilder创建)

class SomeServiceFactory {
    def getWebServiceComponent(a:A) SomeWebServiceComponent
}

FactoryModule看起来像这样

class ApplicationModule extends AbstractModule {
  override def configure() = {
    install(new FactoryModuleBuilder().build(classOf[SomeServiceFactory]))
  }
}

我不介意用我需要的实际课程来注释控制器。

class OneController @Inject()(factory: SomeServiceFactory, bb: BB) extends Controller {
    val webServiceComponent = factory.getWebServiceComponent(bb)
}

class AnotherController @Inject()(factory: SomeServiceFactory, cc: CC) extends Controller {
    val webServiceComponent = factory.getWebServiceComponent(cc)
}

通过此设置,我收到以下类型的错误

No implementation for 'A' annotated with @com.google.inject.assistedinject.Assisted(value=) was bound

我需要了解如何告诉Guice Trait A有两种实现,即BB和CC,并且将在运行时提供选择。

有没有办法实现这个用例?

1 个答案:

答案 0 :(得分:2)

好的,我创建了一个单独的项目来测试整个场景。 它的工作方式与问题的构成方式有关。

事实证明,我正在使用的测试用例目前没有直接使用GuiceInjection。但是,错误消息与GuiceInjection特别相关,如果测试设置正确,我从未调查过。

更改测试基础,解决了问题。