2011-06-07 16 views
10

Estoy tratando de crear una unión de un rasgo genérico utilizando GuiceGuice Y Scala - Inyección de Dependencias genéricos

Vea cómo se define el trait

trait Repository[T] 

Ver la implementación trait

class DomainRepository extends Repository[Domain] 

Mi método configure en DomainPersistenceModule es:

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

La variable cuya dependencia se inyectará es:

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

La inyección se produce aquí:

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

val persistenceService:PersistenceService = 
     injector.getInstance(classOf[DomainPersistenceService]) 

El error es:

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 

Me estoy perdiendo algo? Gracias de antemano

Respuesta

15

Se necesita un TypeLiteral unión como esta: "¿Cómo inyectar clase con el tipo genérico"

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

Ver en el Guice FAQ.

11

Como dice David, necesita un TypeLiteral para enlazar un tipo genérico (recuerde: los tipos genéricos se borran solo a la clase, sin el parámetro de tipo en tiempo de ejecución).

Otra alternativa es algo así como mi biblioteca Scala Guice para construir el TypeLiteral s necesario por Guice de Manifest s de Scala. Si combina el rasgo ScalaModule, entonces podría hacer algo como:

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