在遷移到Play 2.5時,我採用了依賴注入設計模式,包括用於(JDBC)數據庫訪問。使用case class/companion對象模式時的Scala依賴注入
在一流水平,我理解這個概念:
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 _
會導致我想避免的NullPointerException的世界。
在一個依賴注入的世界中,這種常見用例的推薦設計模式是什麼?
案例類並不意味着封裝這樣的「服務」功能,而DI也不是用於與對象一起工作 – cchantep