2011-06-07 20 views
10

Ben Guice Ve Scala - Jenerik bağımlılıklar üzerinde Enjeksiyon

trait nasıl tanımlandığını görün Guice

kullanarak genel özelliğin bağlanmasının oluşturmaya çalışıyorum

trait Repository[T] 

trait uygulanmasını bakın

class DomainRepository extends Repository[Domain] 

DomainPersistenceModule Benim yapılandırmak yöntemidir:

bağımlılık enjekte edilecek olan değişken

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

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

enjeksiyon burada ortaya çıkar:

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

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

hatadır:

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 

Ben bir şey eksik? Şimdiden teşekkürler

cevap

15

Bir TypeLiteral böyle bağlayıcı gerekir: "? Cins sınıfı enjekte nasıl"

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

Bkz Guice FAQ.

11

David'in belirttiği gibi, genel bir tür bağlamak için bir TypeLiteral'a ihtiyacınız vardır (hatırlama - genel türler, çalışma zamanında tip parametresi olmadan yalnızca sınıfa silinir).

Başka bir alternatif, kitaplığım gibi, Scala'nın Manifest s adresinden Guice tarafından istenen TypeLiteral s modelini oluşturmaktır.

bind[Repository[Domain]] 
.annotatedWith[DomainDependency] 
.to[DomainRepository] 
.in(Scopes.SINGLETON) 
: Eğer ScalaModule özellikte karıştırırsanız, o zaman böyle bir şey yapmak mümkün olacaktır