Guice和Scala - 注入泛型依赖关系

ric*_*bbo 10 generics dependency-injection scala guice code-injection

我正在尝试使用Guice创建一个通用特征的绑定

看看如何trait定义

trait Repository[T]
Run Code Online (Sandbox Code Playgroud)

查看trait实施

class DomainRepository extends Repository[Domain]
Run Code Online (Sandbox Code Playgroud)

我的配置方法DomainPersistenceModule是:

def configure() {
   bind(classOf[Repository[Domain]])
     .annotatedWith(classOf[DomainDependency])
     .to(classOf[DomainRepository])
     .in(Scopes.SINGLETON)
}
Run Code Online (Sandbox Code Playgroud)

将注入依赖关系的变量是:

  @Inject
  @DomainDependency
  var repository:Repository[Domain] = _
Run Code Online (Sandbox Code Playgroud)

注射发生在这里:

val injector:Injector = Guice.createInjector(new PersistenceModule())

val persistenceService:PersistenceService =
        injector.getInstance(classOf[DomainPersistenceService])
Run Code Online (Sandbox Code Playgroud)

错误是:

Caused by: com.google.inject.ConfigurationException: Guice configuration errors:

1) No implementation for repository.Repository<domain.Domain> annotated with @module.annotation.DomainDependency() was bound.
  while locating repository.Repository<domain.Domain> annotated with @module.annotation.DomainDependency()
    for field at service.persistence.DomainPersistenceService.repository(DomainPersistenceService.scala:19)
  while locating service.persistence.DomainPersistenceService
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?提前致谢

Dav*_*vid 18

你需要一个像这样的TypeLiteral绑定:

bind(new TypeLiteral[Repository[Domain]] {})
 .annotatedWith(classOf[DomainDependency])
 .to(classOf[DomainRepository])
 .in(Scopes.SINGLETON)
Run Code Online (Sandbox Code Playgroud)

请参阅"如何使用泛型类型注入类?" 在Guice FAQ中.


Ben*_*ngs 13

正如David所说,你需要一个TypeLiteral绑定泛型类型(记住 - 泛型类型被删除到只有类,在运行时没有类型参数).

另一个替代方案是像我的Scala Guice库那样构建TypeLiteralGuice从Scala的Manifests 所需的.如果你混合了这个ScalaModule特性,你就可以做类似的事情:

bind[Repository[Domain]]
 .annotatedWith[DomainDependency]
 .to[DomainRepository]
 .in(Scopes.SINGLETON)
Run Code Online (Sandbox Code Playgroud)