【问题标题】:Using guice when creating a custom Action using ActionBuilder in play在游戏中使用 ActionBuilder 创建自定义动作时使用 guice
【发布时间】:2014-07-20 20:29:58
【问题描述】:

使用 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 会导致它失败,我尝试将其保留为对象,但它无法正确编译。

我怎样才能让它工作?

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

【问题讨论】:

    标签: scala playframework guice


    【解决方案1】:

    经过一些小的更正,您所拥有的似乎已经可以工作了。您所要做的就是将MyAction 的guice 实例化实例注入您的控制器,然后您就可以使用该实例(而不是尝试使用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 需要能够动态实例化类,以便注入依赖项。

    【讨论】:

    • 我不确定我在做什么,但我必须在我的操作中使用类名而不是实例。谢谢!
    • 您好,如果我想给 MyAction 添加参数怎么办?我似乎做不到,例如class MyAction(id: Int = 1) @Inject ....是我做错了什么还是不可能?
    • (userService: UserService) 列表中添加您的参数
    • 我想在我的控制器中添加参数,例如:MyAction("hello" { request => ... }
    【解决方案2】:

    我认为如果你这样使用你的代码应该可以工作:

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

    【讨论】:

    • 最初我的自定义操作是一个“对象”,我可以保持这种状态吗?它是按请求实例化的吗?
    • 我不知道如何将 Guice 与 object 一起使用。但是如果你希望每次都使用同一个实例,你可以在MyAction的定义上面使用Guice的@Singleton注解。
    猜你喜欢
    • 1970-01-01
    • 2021-11-13
    • 2016-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-22
    • 2019-01-10
    相关资源
    最近更新 更多