【发布时间】:2017-02-23 01:27:42
【问题描述】:
在迁移到 Play 2.5 时,我采用了依赖注入设计模式,包括用于 (JDBC) 数据库访问。
在课堂上,我理解这个概念:
class Users @Inject() (db: Database)
但我还没有看到关于当您需要在案例类和伴随对象模式的方法中访问数据库时如何应用此方法的讨论。一个示例基本模型是:
package models
import anorm._
import anorm.SqlParser._
import javax.inject._
import play.api.db._
import play.api.libs.functional.syntax._
import play.api.libs.json._
case class User @Inject() (db: Database) (
id: Option[Long] = None,
email: String
) {
def save = {
id.map { id => User.findById(id) } match {
case None => create
case _ => update
}
}
def create = db.withConnection { implicit conn =>
SQL(
"""INSERT INTO users (email) VALUES ({email})"""
).on(
'email -> email
).executeUpdate()
this
}
def update = ...
}
object User {
val simple = {
get[Option[Long]]("id") ~
get[String]("email") map {
case id ~ email =>
User(id, email)
}
}
def findById(id: Long) = db.withConnection { implicit conn =>
SQL("""SELECT * FROM users WHERE id = {id}""").on('id -> id).as(User.simple.singleOpt)
}
}
这会更改案例类的签名(使其在val simple = { ... } 中无法使用),我无法弄清楚如何在伴随对象中注入/访问数据库。在对象中尝试 @Inject() var db: Database _ 会导致我想避免的 NullPointerExceptions 世界。
在依赖注入的世界中,这种常见用例的推荐设计模式是什么?
【问题讨论】:
-
case 类并不是为了封装这样的“服务”功能,DI 也不是为了与对象一起工作而设计的
标签: scala playframework dependency-injection playframework-2.5