Guice And Scala - Инъекция по родовым зависимостям - PullRequest
10 голосов
/ 08 июня 2011

Я пытаюсь создать привязку общей черты, используя 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

Я что-то упустил? Заранее спасибо

Ответы [ 2 ]

18 голосов
/ 08 июня 2011

Вам нужна привязка TypeLiteral , например:

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

TypeLiteral - это специальный класс, который позволяет указывать полный параметризованный тип. По сути, вы не можете создать экземпляр класса с параметром универсального типа.

Также взгляните на этот ответ .

См. "Как внедрить класс с универсальным типом?" в Guice FAQ .

13 голосов
/ 08 июня 2011

Как говорит Дэвид, вам нужно TypeLiteral для привязки универсального типа (помните - универсальные типы стираются только для класса, без параметра типа во время выполнения).

Другой альтернативой являетсячто-то вроде моей библиотеки Scala Guice для создания TypeLiteral s, необходимых Гису из Manifest s Scala.Если вы смешаете черту ScalaModule, вы сможете сделать что-то вроде:

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