[S'il vous plaît pardonnez-moi pour la longue question, je suis encore à apprendre à Scala.]Comment lier correctement un trait à son impl lorsque l'on a plus tard paramètres implicites
J'essaie de lier un trait générique à son impl générique qui a des paramètres implicites. Voici le code de nettoyage:
trait PersistenceService[T <: SomeOtherClass] {
def persist(record: T): Future[Unit]
}
class MongoPersistenceService[T <: SomeOtherClass] @Inject()(implicit ec: ExecutionContext, tag: ClassTag[T]) extends PersistenceService[T] {
val collectionName: String = tag.runtimeClass.getSimpleName
val databaseName = "someDatabase"
def db: Future[DefaultDB] = MongoConnectionWrapper.getMongoConnection("mongodb://127.0.0.1", "27017")
.flatMap(_.database(databaseName))
def collection: Future[BSONCollection] = db.map(_.collection(collectionName))
def persist(record: T): Future[Unit] = {
val result = for {
col <- collection
writeResult <- col.insert(record)
} yield writeResult
result.recoverWith {
case WriteResult.Code(11000) => throw RecordAlreadyExistsException(record,
"")
}.map(_ =>())
}
def read(id: BSONObjectID): Future[T] = {
val query = BSONDocument("_id" -> id)
val readResult: Future[T] = for {
coll <- collection
record <- coll.find(query).requireOne[T]
} yield record
readResult.recoverWith {
case NoSuchResultException => throw RecordNotFoundException(id)
}
}
}
J'utilise Play, ReactiveMongo et ScalaGuice (toutes les dernières versions). Alors, voici ma principale tout de liaison de classe Module:
class Module(env: Environment, config: Configuration) extends AbstractModule with ScalaModule {
def configure(): Unit = {
bind[PersistenceService[_]].to[MongoPersistenceService[_]] // Also tried with specific class instead of _ but not working either
}
}
Et disons que j'ai un de mon contrôleur avec dépendance PersistenceService comme ceci:
class PersistenceServiceController @Inject()(val PersistenceService: PersistenceService[Bar], cc ControllerComponents) extends AbstractController(cc) { ... }
Et le modèle (comme vous pouvez probablement le deviner) avec son implicits lecteur/enregistreur:
case class Bar() extends SomeOtherClass() {}
object Bar {
implicit object BarReader extends BSONDocumentReader[Bar] {
def read(doc: BSONDocument): Bar = { ... }
}
implicit object BarWriter extends BSONDocumentWriter[Bar] {
def write(bar: Bar): BSONDocument = { ... }
}
}
Avec toutes ces étoffes, je commence à l'exception d'exécution suivantes:
com.google.inject.CreationException: Unable to create injector, see the following errors:
1) No implementation for reactivemongo.bson.BSONDocumentReader<Bar> was bound.
while locating reactivemongo.bson.BSONDocumentReader<Bar>
for the 2nd parameter of MongoPersistenceService.<init>(MongoPersistenceService.scala:15)
at Module.configure(Module.scala:14) (via modules: com.google.inject.util.Modules$OverrideModule -> Module)
2) No implementation for reactivemongo.bson.BSONDocumentWriter<Bar> was bound.
while locating reactivemongo.bson.BSONDocumentWriter<Bar>
for the 3rd parameter of persistence.MongoPersistenceService.<init>(MongoPersistenceService.scala:15)
at Module.configure(Module.scala:14) (via modules: com.google.inject.util.Modules$OverrideModule -> Module)
3) No implementation for scala.reflect.ClassTag<Bar> was bound.
while locating scala.reflect.ClassTag<Bar>
for the 5th parameter of MongoPersistenceService.<init>(MongoPersistenceService.scala:15)
at Module.configure(Module.scala:14) (via modules: com.google.inject.util.Modules$OverrideModule -> Module)
Donc, clairement, les choses que ma classe MongoPersistenceService devrait obtenir dans le contexte d'exécution manquent comment. Je comprends que Play est un peu magique fournissant le contexte d'exécution lorsque vous configurez vos affaires correctement avec guice. Mais dans ce cas, on dirait que ça ne marche pas.
Comment puis-je résoudre ce problème?