Using guice when creating a custom Action using Ac

2019-04-11 13:28发布

How can I use guice when creating a custom Action using ActionBuilder?

It seems to complain with "not found: value MyAction" if I change the ActionBuilder from a object to a class.

I have this but it doesn't work:

case class MyModel(name: String, request: Request[A]) extends WrappedRequest[A](request)

class MyAction @Inject()(userService: UserService) extends ActionBuilder[MyModel] {
  def invokeBlock[A](request: Request[A], block: (MyModel[A]) => Future[SimpleResult]) = {
    val abc = loadAbc(request)
    block(new MyModel(abc, request))
  }

  def loadAbc(rh: RequestHeader): String {
    "abc" // just for testing
  }
}

So changing it from an object to a class causes it to fail, and I tried keeping it as an object but then it doesn't compile correctly.

How can I get this to work?

I have it working just fine in my controllers.

2条回答
相关推荐>>
2楼-- · 2019-04-11 13:49

With a few minor corrections, what you've got seems to work already. All you've got to do is inject the guice-instantiated instance of MyAction into your controller, and then you can use the instance (rather than trying to use the MyAction class name).

This works with Play 2.3:

import scala.concurrent.Future
import javax.inject.{Inject, Singleton}
import play.api.mvc._

class UserService() {
  def loadAbc(rh: RequestHeader) = "abc"
}

class MyModel[A](val name: String, request: Request[A]) extends WrappedRequest[A](request)

class MyAction @Inject()(userService: UserService) extends ActionBuilder[MyModel] {
  def invokeBlock[A](request: Request[A], block: (MyModel[A]) => Future[Result]) = {
    val abc = userService.loadAbc(request)
    block(new MyModel(abc, request))
  }
}

@Singleton
class Application @Inject() (myAction: MyAction) extends Controller {
  def index = myAction { request =>
    Ok(request.name)
  }
}

You can't use object because that violates the design of Guice. object is a singleton instantiated by Scala itself and cannot have instance variables, whereas Guice needs to be able to instantiate classes on the fly so that it can inject dependencies.

查看更多
再贱就再见
3楼-- · 2019-04-11 14:01

I think your code should work if you use it like this:

class MyClass @Inject()(myAction: MyAction) {
  val echo = myAction { request =>
    Ok("Got request [" + request + "]")
  }
}
查看更多
登录 后发表回答