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
Я что-то упустил? Заранее спасибо
2 ответа:
Вам нужна TypeLiteral привязка вот так:
bind(new TypeLiteral[Repository[Domain]] {}) .annotatedWith(classOf[DomainDependency]) .to(classOf[DomainRepository]) .in(Scopes.SINGLETON)
См. раздел " как ввести класс с универсальным типом?"в Guice FAQ .
Как говорит Дэвид, вам нужен
TypeLiteral
для привязки универсального типа (помните - универсальные типы стираются только в класс, без параметра type во время выполнения).Другой альтернативой является что-то вроде моей библиотеки Scala Guice , чтобы построить
TypeLiteral
s, необходимые Guice изManifest
S Scala. если вы смешаете вScalaModule
черту, вы сможете сделать что-то вроде:bind[Repository[Domain]] .annotatedWith[DomainDependency] .to[DomainRepository] .in(Scopes.SINGLETON)