Tim Joseph Tim Joseph - 23 days ago 9
Scala Question

Play Framework: Dependency Inject Action Builder

since Play Framework 2.4 there is the possibility to use dependency injection (with Guice).

Before I used objects (for example

AuthenticationService
) in my ActionBuilders:

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


Now
AuthenticationService
is not an object anymore, but a class. How can I still use the
AuthenticationService
in my
ActionBuilder
?

Answer Source

Define your action builders inside a trait with the authentication service as an abstract field. Then mix them into your controllers, into which you inject the service. For example:

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(...)
      ...
    }
  }
}

and the controller:

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