Платформа игр: инициатор вложений

поскольку в 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 (...)
    ...
  }
}

Теперь AuthenticationService больше не объект, а класс. Как я могу использовать AuthenticationService в моем ActionBuilder?

Ответы

Ответ 1

Определите свои разработчики действий внутри признака с помощью службы проверки подлинности как абстрактного поля. Затем смешайте их с контроллерами, в которые вы вводите услугу. Например:

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!")
  }
}

Ответ 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. Я обошел это довольно легко, просто отправив службу в подпись метода, а...

class Authentication @Inject()(authenticationService: AuthenticationService) extends Controller with ActionBuilders {

  def testAuth = AuthenticatedAction(authenticationService).async { implicit request =>
    Future.successful(Ok("Authenticated!"))
  }

}