Guice 使用 Providers 或 FactoryModuleBuilder 辅助注入
Guice Assisted Inject with Providers or FactoryModuleBuilder
这是一个奇怪的用例,我需要一些帮助来弄清楚如何结合使用 Assisted/Providers/FactoryModuleBuilders。忽略 @Singleton
的缺失。这只是一个例子。
属于我无法更改的库的一组特征具有以下模式。它使用蛋糕模式。
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 特征 A 有两个实现,即 BB 和 CC,并且将在运行时提供选择。
有没有办法实现这个用例?
好的,我创建了一个单独的项目来测试整个场景。
它按照问题的框架运作。
事实证明,我使用的测试用例目前并未直接使用 GuiceInjection。但是,错误消息与 GuiceInjection 特别相关,以至于我从未调查过测试设置是否正确。
更换测试基地,问题解决。
这是一个奇怪的用例,我需要一些帮助来弄清楚如何结合使用 Assisted/Providers/FactoryModuleBuilders。忽略 @Singleton
的缺失。这只是一个例子。
属于我无法更改的库的一组特征具有以下模式。它使用蛋糕模式。
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 特征 A 有两个实现,即 BB 和 CC,并且将在运行时提供选择。
有没有办法实现这个用例?
好的,我创建了一个单独的项目来测试整个场景。 它按照问题的框架运作。
事实证明,我使用的测试用例目前并未直接使用 GuiceInjection。但是,错误消息与 GuiceInjection 特别相关,以至于我从未调查过测试设置是否正确。
更换测试基地,问题解决。