在Play中使用ActionBuilder创建自定义Action时使用guice

时间:2014-05-31 01:05:06

标签: scala playframework guice

如何在使用ActionBuilder创建自定义Action时使用guice?

如果我将ActionBuilder从一个对象更改为一个类,似乎抱怨“找不到:值MyAction”。

我有这个,但它不起作用:

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
  }
}

因此将其从object更改为class会导致其失败,我尝试将其保留为对象,但之后无法正确编译。

我怎样才能让它发挥作用?

我在控制器中工作得很好。

2 个答案:

答案 0 :(得分:2)

通过一些小的修正,你所拥有的似乎已经有效了。您所要做的就是将guice实例化的MyAction实例注入您的控制器,然后您可以使用该实例(而不是尝试使用MyAction类名称。)

这适用于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)
  }
}

您无法使用object,因为这违反了Guice的设计。 object是由Scala本身实例化的单例,不能有实例变量,而Guice需要能够实时实例化类,以便它可以注入依赖项。

答案 1 :(得分:1)

我认为如果您使用它,您的代码应该可以使用:

class MyClass @Inject()(myAction: MyAction) {
  val echo = myAction { request =>
    Ok("Got request [" + request + "]")
  }
}