自定义操作具有多个隐式参数

时间:2013-08-02 09:01:26

标签: scala playframework-2.0 playframework-2.1 slick

我们的Play应用程序使用Slick作为数据访问层。这意味着在我们的应用程序中的几乎每个操作中,我们都需要在范围内隐式提供当前Request和Slick的数据库Session

我想编写一个自定义Action来执行此操作,因此我们只需要一行来执行此操作。我想要做的是以这样的方式写它,我可以写这样的东西:

def someAction = DBAction { implicit request, session =>
  // body with implicit request and session on scope

但这不是有效的语法。使用元组不起作用,因为它无法隐式解压动作体中的元组。是否可以创建一个自定义操作,将多个隐式参数传递给正文?我该怎么做?

2 个答案:

答案 0 :(得分:4)

你不能隐含2个这样的变量。

但是您的自定义操作可以返回WrappedRequest(封装请求和会话的对象),您可以在此包装请求和会话之间定义隐式转换。

尝试此示例,源自此class

sealed case class DBRequest(session: Session, private val request: Request[AnyContent])
  extends WrappedRequest(request)

trait DBController extends Controller {

  // Implicit conversion from DBRequest to Session
  implicit def session(implicit request: DBRequest) = request.session

  def DBAction(action: DBRequest => Result) = Action { request =>
    database.withSession { session =>
      action(DBRequest(session, request))
    }
  }
}

object MyController extends Controller with DBController {

  def myAction = DBAction { implicit request =>
    println(session)
  }
}

答案 1 :(得分:2)

@senia是对的,currying需要用来做这件事。这实际上是在Play docs中解决的,但这是我最近错过的一个补充。

为了寻找此人的未来参考,我的自定义操作现在看起来像这样:

def DBAction(action: Request[AnyContent] => Session => Result) = {
  Action { request =>
    database.withSession { session =>
       action(request)(session)
    }
  }
}

然后我可以通过以下方式使用:

def someAction = DBAction { implicit request => implicit session => /* body */ }