【问题标题】:Play Framework: Dependency Inject Action BuilderPlay 框架:依赖注入动作生成器
【发布时间】:2015-09-14 22:14:14
【问题描述】:

从 Play Framework 2.4 开始,可以使用依赖注入(使用 Guice)。

在我的 ActionBuilders 中使用对象(例如 AuthenticationService)之前:

object AuthenticatedAction extends ActionBuilder[AuthenticatedRequest] {
  override def invokeBlock[A](request: Request[A], block: (AuthenticatedRequest[A]) => Future[Result]): Future[Result] = {
    ...
    AuthenticationService.authenticate (...)
    ...
  }
}

现在AuthenticationService 不再是一个对象,而是一个类。我怎样才能在我的ActionBuilder 中使用AuthenticationService

【问题讨论】:

    标签: scala playframework dependency-injection guice guice-3


    【解决方案1】:

    使用身份验证服务作为抽象字段在 trait 中定义您的操作构建器。然后将它们混合到您的控制器中,然后将服务注入其中。例如:

    trait MyActionBuilders {
      // the abstract dependency
      def authService: AuthenticationService
    
      def AuthenticatedAction = new ActionBuilder[AuthenticatedRequest] {
        override def invokeBlock[A](request: Request[A], block(AuthenticatedRequest[A]) => Future[Result]): Future[Result] = {
          authService.authenticate(...)
          ...
        }
      }
    }
    

    和控制器:

    @Singleton
    class MyController @Inject()(authService: AuthenticationService) extends Controller with MyActionBuilders {    
      def myAction(...) = AuthenticatedAction { implicit request =>
        Ok("authenticated!")
      }
    }
    

    【讨论】:

    • 我需要在MyController中的authService之前添加val,否则编译器会抱怨authService方法没有定义
    • 这对我来说不管是 val 还是 def 都不起作用,说 Controller 类需要是抽象的,因为 def/val 没有定义
    【解决方案2】:

    我不喜欢上面示例中要求继承的方式。但显然可以简单地将object 包装在类中:

    class Authentication @Inject()(authService: AuthenticationService) {
      object AuthenticatedAction extends ActionBuilder[Request] {
        def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]) = {
          // Do your thing wit the authService...
          block(request)
        }
      }
    }
    
    class YourController @Inject() (val auth: Authentication) extends Controller (
      def loggedInUser = auth.AuthenticatedAction(parse.json) { implicit request =>
        // ...
      }
    }
    

    【讨论】:

      【解决方案3】:

      我喜欢接受的答案,但由于某种原因,编译器无法识别 authService 引用。只需在方法签名中发送服务,我就很容易解决这个问题,la...

      class Authentication @Inject()(authenticationService: AuthenticationService) extends Controller with ActionBuilders {
      
        def testAuth = AuthenticatedAction(authenticationService).async { implicit request =>
          Future.successful(Ok("Authenticated!"))
        }
      
      }
      

      【讨论】:

      • 我刚刚检查过,我认为没有理由接受的答案不能编译!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-06
      • 2010-09-14
      • 2015-09-30
      • 2016-08-19
      • 2016-11-29
      • 1970-01-01
      相关资源
      最近更新 更多