Guice和Scala-泛型依赖项的注入



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

查看trait是如何定义的

trait Repository[T]

参见trait实现

class DomainRepository extends Repository[Domain]

我在DomainPersistenceModule中的配置方法是:

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

将注入依赖性的变量为:

  @Inject
  @DomainDependency
  var repository:Repository[Domain] = _

注射发生在这里:

val injector:Injector = Guice.createInjector(new PersistenceModule())
val persistenceService:PersistenceService =
        injector.getInstance(classOf[DomainPersistenceService])

错误为:

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

我是不是错过了什么?提前感谢

您需要这样的TypeLiteral绑定:

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

TypeLiteral是一个特殊的类,允许您指定一个完整的参数化类型。基本上,不能用泛型类型参数实例化类。

另外,看看这个答案。

请参阅Guice常见问题解答中的"如何用泛型类型注入类?"。

正如David所说,您需要一个TypeLiteral来绑定泛型类型(请记住,泛型类型在运行时只擦除到类中,没有类型参数)。

另一种选择是使用类似于我的Scala Guice库的方法,从Scala的Manifest s中构建Guice所需的TypeLiteral s。如果您混合使用ScalaModule特性,那么您就可以执行以下操作:

bind[Repository[Domain]]
 .annotatedWith[DomainDependency]
 .to[DomainRepository]
 .in(Scopes.SINGLETON)

最新更新