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
?
Play is rock-solid and used by hundreds of thousands of Java and Scala developers every month. Play is still extremely relevant to today's application and web development and has a passionate and very capable community around it ensuring that it has many good years left.
What is an Action? Most of the requests received by a Play application are handled by an action. An action is basically a Java method that processes the request parameters, and produces a result to be sent to the client. public Result index(Http. Request request) { return ok("Got request " + request + "!"
In object-oriented programming (OOP) software design, dependency injection (DI) is the process of supplying a resource that a given piece of code requires. The required resource, which is often a component of the application itself, is called a dependency.
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!")
}
}
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 =>
// ...
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With