【问题标题】:Use of implicits in Play 2.5 ActionRefiner在 Play 2.5 ActionRefiner 中使用隐式
【发布时间】:2016-07-19 19:26:28
【问题描述】:

我正在尝试创建自己的 ActionRefiner 以适应身份验证,但由于某种原因,编译器不允许我在 refine[A] 函数中使用隐式变量...我有以下代码:

trait Auth {
  object AuthenticatedAction extends ActionBuilder[AuthRequest] with ActionRefiner[Request, AuthRequest] {

    def refine[A](request: Request[A])(implicit userCollection: UserCollection, ex: ExecutionContext): Future[Either[Result, AuthRequest[A]]] = {
      request.session.get("username") match {
        case Some(username) => userCollection.findByEmail(username).map { userOpt =>
          userOpt.map(new AuthRequest(_, request)).toRight(Results.Redirect(routes.LoginController.login()))
        }
        case None => Future.successful(Left(Results.Redirect(routes.LoginController.login())))
      }
    }
  }
}

class AuthRequest[A](val user: User, request: Request[A]) extends WrappedRequest[A](request)

Scala 编译器告诉我方法refine[A](request: R[A]): Future[Either[Result, P[A]]] 没有定义。当我删除它注册的隐式变量时,这让我没有 UserCollection...

那么,我该如何正确使用 ActionRefiner?

【问题讨论】:

  • 这是因为当您添加隐式参数时,该函数不再匹配来自ActionRefinerrefine 的抽象定义。这就是您收到“未定义”消息的原因。

标签: scala playframework-2.0


【解决方案1】:

感谢this topic 我找到了让它工作的方法。我可以在 trait 中定义 UserCollection 并从我的控制器传递它,而不是使用隐式,如下所示:

trait Auth {
  def userCollection: UserCollection

  object AuthenticatedAction extends ActionBuilder[AuthRequest] with ActionRefiner[Request, AuthRequest] {
    def refine[A](request: Request[A]): Future[Either[Result, AuthRequest[A]]] = {
      ...
    }
  }
}

class HomeController @Inject()(val userCollection: UserCollection)(implicit executionContext: ExecutionContext) extends Controller with Auth {
  def index = AuthenticatedAction { implicit request =>
    Ok(s"Hello ${request.user.name}")
  }
}

我刚刚习惯了使用隐式,我完全忘记了这一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-31
    • 2016-08-18
    • 1970-01-01
    • 2017-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多