Reputation: 277
Let's say I want to encapsulate functionality of a class, meaning I want to introduce a proxy between clients and this particular class. For example, Play's Result
class has the following method:
/**
* Adds headers to this result.
*
* For example:
* {{{
* Ok("Hello world").withHeaders(ETAG -> "0")
* }}}
*
* @param headers the headers to add to this result.
* @return the new result
*/
def withHeaders(headers: (String, String)*): Result = {
copy(header = header.copy(headers = header.headers ++ headers))
}
Let's assume that I don't want to use this method directly, but instead I want to use a proxy. So instead of calling Redirect(controllers.app.routes.Application.index).withHeaders(<XYZ>)
I want to call my own method which subsequently calls .withHeaders(<XYZ>)
:
Redirect(controllers.app.routes.Application.index).customWithHeaders(<XYZ>)
How can this be implemented? Can this be done by implementing a trait which will be extended by controllers?
Upvotes: 0
Views: 51
Reputation: 14825
import play.api.mvc.Result
implicit class ResultUtils (result: Result) {
def withCustomHeaders(pairs: (String, String)*): Result = result.withHeaders(pairs: _*)
}
with ResultUtils in scope, you can now do Redirect(something).withCustomHeaders
Package Object
package object common {
implicit class ResultUtils (result: Result) {
def withCustomHeaders(pairs: (String, String)*): Result = result.withHeaders(pairs: _*)
}
}
import common._ //import common and get this class in scope
Trait
trait Implicits {
implicit class ResultUtils (result: Result) {
def withCustomHeaders(pairs: (String, String)*): Result = result.withHeaders(pairs: _*)
}
}
class ApplicationController @Inject() () extends Controller extends Something with Implicits {
def fooAction = Action { Ok("bar").withCustomHeaders("foo" -> "bar") }
}
Upvotes: 1