我有多个共享相同属性的模型类。因此,我创建了一个特征,例如:

trait Player extends Temp {

  val gameId: BSONObjectID

  val personalDetails: abc.PersonalDetails // <- comes from shared library

}

case class FootballPlayer(var _id: Option[BSONObjectID] = None,
                         gameId: BSONObjectID,
                         personalDetails: abc.PersonalDetails,
                         var created: Option[DateTime] = None,
                         var updated: Option[DateTime] = None
                        ) extends Player

case class VideogamePlayer(var _id: Option[BSONObjectID] = None,
                         gameId: BSONObjectID,
                         personalDetails: abc.PersonalDetails,
                         var created: Option[DateTime] = None,
                         var updated: Option[DateTime] = None
                        ) extends Player

所有这些模型都定义了play.api.libs.json.Readsplay.api.libs.json.OWrites作为伴随对象。

例如:
object FootballPlayer {

  import play.api.libs.functional.syntax._
  import play.api.libs.json.Reads._
  import play.api.libs.json._
  import reactivemongo.play.json.BSONFormats.BSONObjectIDFormat

  implicit val footballPlayerReads: Reads[FootballPlayer] = (
    (__ \ "_id").readNullable[BSONObjectID].map(_.getOrElse(BSONObjectID.generate)).map(Some(_)) and
      (__ \ "gameId").read[BSONObjectID] and
      (__ \ "personalDetails").read[abc.PersonalDetails] and
      (__ \ "created").readNullable[DateTime].map(_.getOrElse(new DateTime())).map(Some(_)) and
      (__ \ "updated").readNullable[DateTime].map(_.getOrElse(new DateTime())).map(Some(_))
    ) (FootballPlayer.apply _)


  implicit val sharedPersonalDetailsWrites: Writes[abc.PersonalDetails] = abc.PersonalDetails.sharedPersonalDetailsWrites

  implicit val footballPlayerWrites: OWrites[FootballPlayer] = (
    (__ \ "_id").writeNullable[BSONObjectID] and
      (__ \ "gameId").write[BSONObjectID] and
      (__ \ "personalDetails").write[abc.PersonalDetails] and
      (__ \ "created").writeNullable[DateTime] and
      (__ \ "updated").writeNullable[DateTime]
    ) (unlift(FootballPlayer.unapply))

}

现在,我想将它们存储在不同的集合中,但是我只想拥有一个DAO,因此我实现了以下内容:
trait PlayerDAO[T <: Player] {

  def findById(_id: BSONObjectID)(implicit reads: Reads[T]): Future[Option[T]]

  def insert(t: T)(implicit writes: OWrites[T]): Future[T]

}

class MongoPlayerDAO[T <: Player] @Inject()(
                                           playerRepository: PlayerRepository[T]
                                         ) extends PlayerDAO[T] {

  def findById(_id: BSONObjectID)(implicit reads: Reads[T]): Future[Option[T]] = playerRepository.findById(_id)

  def insert(t: T)(implicit writes: OWrites[T]): Future[T] = playerRepository.insert(t).map(_ => t)

}

然后,我有以下存储库:
class PlayerService[T <: Player] @Inject()(playerDAO: PlayerDAO[T])(implicit reads: Reads[T], writes: OWrites[T]) {

  def findById(_id: BSONObjectID): Future[Option[T]] = playerDAO.findById(_id)


  def save(t: T): Future[T] = playerDAO.save(t)

}

我的模块如下所示:
class PlayerModule extends AbstractModule with ScalaModule {

  def configure() {
    bind[PlayerDAO[FootballPlayer]].to[MongoPlayerDAO[FootballPlayer]]
    bind[PlayerDAO[VideogamePlayer]].to[MongoPlayerDAO[VideogamePlayer]]
    // ...
    ()
  }
}

然后在我的Play Controller 中注入(inject)以下内容:
import models.FootballPlayer._
import models.VideogamePlayer._

class PlayerController @Inject()(
                                 val messagesApi: MessagesApi,
                                 footballPlayerService: PlayerService[FootballPlayer],
                                 videogamePlayerService: PlayerService[VideogamePlayer]
                               ) extends Controller with I18nSupport

但是,不幸的是,我得到以下异常:



我怎样才能解决这个问题?

最佳答案

进行dao注入(inject)时,可能无法找到隐式上下文。尝试在定义绑定(bind)的AbstractModule中包含隐式函数。

编辑

检查我对git的解决方案。 Here

我试图模仿您想做的任何事情,并且工作正常。

我不确定您当前的代码是什么问题,因为我无法访问整个代码,但是我认为这与应用程序搜索OWrites和Reads隐式表示Player而不是FootballPlayerVideoGamePlayer有关

关于scala - Scala Play应用程序未绑定(bind)OWrites和Reads的实现,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43569720/

10-10 12:56