【发布时间】:2017-09-20 01:13:00
【问题描述】:
我有多个模型类,它们都共享相同的属性。出于这个原因,我创建了一个特征,例如:
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.Reads 和 play.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 控制器中,我注入以下内容:
import models.FootballPlayer._
import models.VideogamePlayer._
class PlayerController @Inject()(
val messagesApi: MessagesApi,
footballPlayerService: PlayerService[FootballPlayer],
videogamePlayerService: PlayerService[VideogamePlayer]
) extends Controller with I18nSupport
但是,不幸的是,我得到了以下异常:
1) 没有实现 play.api.libs.json.OWrites 已绑定。 2) 没有 play.api.libs.json.OWrites 的实现 被束缚。 3)没有实现 play.api.libs.json.Reads 已绑定。 4) 没有 play.api.libs.json.Reads 的实现 被绑定了。
我该如何解决这个问题?
【问题讨论】:
-
1.
OWrites和Reads的定义没有说明。 2. 在case class中使用var可能不是一个好主意。 -
OWrites&Reads在对应的伴随对象中定义,并在PlayerController中导入。 -
你能发布你是如何在伴随对象中定义 OWrites 和 Reads 的吗?
-
@SumeetSharma 请查看我更新的问题。
-
@JohnDoe 你能分享你的 playerrepository 定义吗?
标签: scala playframework guice