Play Framework:Dependency Inject Action Builder

Tim*_*eph 16 dependency-injection scala guice playframework guice-3

从Play Framework 2.4开始,就有可能使用依赖注入(使用Guice).

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

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

现在AuthenticationService不再是一个对象,而是一个类.我怎么还能使用AuthenticationService我的ActionBuilder

Mik*_*ame 27

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

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(...)
      ...
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

和控制器:

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

  • 我需要在`MyController`中的`authService`之前添加`val`,否则编译器会抱怨authService方法没有定义 (3认同)

Cia*_*tic 18

我不喜欢在上面的例子中需要继承的方式.但显然可以简单地包装一个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 =>
    // ...
  }
}
Run Code Online (Sandbox Code Playgroud)