Play Framework:依赖注入动作生成器
Play Framework: Dependency Inject Action Builder
从 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
不再是一个对象,而是一个 class。我怎样才能在 ActionBuilder
中使用 AuthenticationService
?
在特征内定义您的操作构建器,并将身份验证服务作为抽象字段。然后将它们混合到您的控制器中,您将服务注入其中。例如:
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!")
}
}
我喜欢接受的答案,但出于某种原因,编译器无法识别 authService 引用。我通过在方法签名中发送服务很容易地解决了这个问题,一个 la...
class Authentication @Inject()(authenticationService: AuthenticationService) extends Controller with ActionBuilders {
def testAuth = AuthenticatedAction(authenticationService).async { implicit request =>
Future.successful(Ok("Authenticated!"))
}
}
我不喜欢上面示例中要求继承的方式。但显然可以简单地将 object
包裹在 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 =>
// ...
}
}
从 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
不再是一个对象,而是一个 class。我怎样才能在 ActionBuilder
中使用 AuthenticationService
?
在特征内定义您的操作构建器,并将身份验证服务作为抽象字段。然后将它们混合到您的控制器中,您将服务注入其中。例如:
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!")
}
}
我喜欢接受的答案,但出于某种原因,编译器无法识别 authService 引用。我通过在方法签名中发送服务很容易地解决了这个问题,一个 la...
class Authentication @Inject()(authenticationService: AuthenticationService) extends Controller with ActionBuilders {
def testAuth = AuthenticatedAction(authenticationService).async { implicit request =>
Future.successful(Ok("Authenticated!"))
}
}
我不喜欢上面示例中要求继承的方式。但显然可以简单地将 object
包裹在 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 =>
// ...
}
}