[请原谅我长期提问,我还在学习Scala。]
我试图将通用特征绑定到具有隐式参数的通用impl。这是清理代码:
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)
}
}
}
我使用Play,ReactiveMongo和ScalaGuice(所有最新版本)。所以这是我的主要模块类绑定所有内容:
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
}
}
让我们说我的控制器之一依赖PersistenceService这样:
class PersistenceServiceController @Inject()(val PersistenceService: PersistenceService[Bar], cc ControllerComponents) extends AbstractController(cc) { ... }
模型(你可以猜到)带有读者/作者:
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 = { ... }
}
}
有了这些东西,我得到了以下运行时异常:
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)
很明显,我的类MongoPersistenceService应该在执行上下文中获取的内容缺少一些方法。我知道,当你用guice正确设置你的东西时,Play有点神奇地提供执行上下文。但在这种情况下,看起来它不起作用。
我该如何解决?
答案 0 :(得分:0)
我对这个感觉很糟糕,但是找到问题的错误信息非常明显。要解决此问题,我必须手动绑定BSONDocumentReader[Bar]
,BSONDocumentWriter[Bar]
和ClassTag[Bar]
的impl。
我将代码重构为更简单的代码。 但是想让其他人知道这是什么问题。