运维开发网

使用案例类/伴随对象模式时的Scala依赖注入

运维开发网 https://www.qedev.com 2020-07-05 19:42 出处:网络 作者:运维开发网整理
在迁移到Play 2.5时,我采用了依赖注入设计模式,包括(JDBC)数据库访问. 在课堂上,我理解这个概念: class Users @Inject() (db: Database) 但是,当您需要在案例类和伴随对象模式的方法中进行数据库访问时,我还没有看到过如何应用这种方法的讨论.一个示例基本模型是: package models import anorm._ import anorm.Sq
在迁移到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)
    }
}

这会更改case类的签名(使其在val simple = {…}中无法使用),我无法弄清楚如何在随播对象中注入/访问db.尝试@Inject()var db:对象中的Database _会导致我想避免的NullPointerExceptions世界.

在依赖注入的世界中,这种常见用例的推荐设计模式是什么?

常见的模式是将数据库功能放在单独的类中.在您的情况下,只留下用户的数据:

case class User(id: Option[Long] = None, email: String)

并将数据库功能放入一个单独的类中:

class UserRepository @Inject()(db: Database) {
    def save(user: User) = { ... }
    def create() : User = { ... }
    def findById(id: Long) : Option[User] = { ... }
}

不知道如何在代码中使用User对象.但是使用该模式,您不会携带对数据库的引用,每个用户对象基本上将持久性实现泄露到使用用户对象的任何位置.也许你想拥有这个但是你在val simple = …中创建一个User对象的方式向我表明你想要创建只包含数据的用户对象.

现在您要传递用户对象,并且只有在需要数据库功能时才注入UserRepository.

这并不能完全解决您关于依赖注入伴随对象的问题,但无论如何都可能有所帮助.

0

精彩评论

暂无评论...
验证码 换一张
取 消