Play Framework: Dependency Inject Action Builder

后端 未结 3 1899
猫巷女王i
猫巷女王i 2020-12-14 19:30

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

Before I used objects (for example AuthenticationService) in

相关标签:
3条回答
  • 2020-12-14 20:05

    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!")
      }
    }
    
    0 讨论(0)
  • 2020-12-14 20:20

    I like accepted answer but for some reason the compiler would not recognize the authService reference. I got around this pretty easily by just sending the service in the method signature, a la...

    class Authentication @Inject()(authenticationService: AuthenticationService) extends Controller with ActionBuilders {
    
      def testAuth = AuthenticatedAction(authenticationService).async { implicit request =>
        Future.successful(Ok("Authenticated!"))
      }
    
    }
    
    0 讨论(0)
  • 2020-12-14 20:28

    I didn't like the way one was required to inherit in the above example. But apparently it's possible to simply wrap a object inside class:

    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 =>
        // ...
      }
    }
    
    0 讨论(0)
提交回复
热议问题