【问题标题】:@Inject object null: Play dependency injection@Inject object null:播放依赖注入
【发布时间】:2016-06-02 01:27:28
【问题描述】:

我在我的控制器类中使用依赖注入进行了实例化。当我尝试在其他地方使用 @inject 注释使用该对象时,我得到空值。这是我的代码框架。

@singleton
class ServiceClient(ws: WSClient, config: Configuration) {
 def get response() {...}
}

class App @Inject()(client: ServiceClient) extends Controller {

   def getItems = Action  {
     Obj()
   }
}

case class Obj() {

  @Inject
  var client: ServiceClient = _
  def doStuff() {
    client.getResponse() //client is null so get null pointer exception.
    ....
  }
}

Obj 中的@Inject 似乎从来没有工作过。我的客户对象始终为空。 (我不想将客户端作为参数传递给 Obj。)我的期望是在控制器中创建的 ServiceClient 对象应该被注入到 Obj() 中。我做错了什么?

更新

将 Obj 注入控制器不是一种选择。 (在我的应用程序中,Obj 在运行时实例化了我的一些复杂规则,使用反射)。另外我不想在 Obj 中注入构造函数。 我正在寻找控制器外的 ServiceClient 字段注入。

更新2

我能够使用

解决问题
var client: ServiceClient = play.api.Play.current.injector.instanceOf(classOf[ServiceClient]) 

在 Obj 类中。 但是,play.api.Play.current 在 play 2.5 中已被弃用,所以我仍然有点被警告所困扰。

【问题讨论】:

    标签: scala dependency-injection playframework-2.1


    【解决方案1】:

    你不能在不询问 DI 框架的情况下将依赖项注入到类实例中。在您的代码中,您手动实例化Obj,这意味着依赖注入魔法没有发生。为了向Obj 类注入依赖关系,它的实例化应该由DI 框架处理。你可以在这里做的是:

    1. ServiceClient 注入Obj 构造函数或归档:

      class Obj @Inject() (client: ServiceClient) {
        //
      }
      

      使用简单类而不是案例类是有意义的,因为案例类听起来更像是内部包含不可变数据的“数据”类,而不是服务或一些帮助类。实际上,您当前对 Obj 类的定义应该可以工作。

    2. Obj 和(或,根据您的需要)ServiceClient 注入您的 App 类:

      class App @Inject()(obj: Obj, client: ServiceClient) extends Controller {
        def getItems = Action  {
          obj.doStuff()
        }
      }
      

    我建议您阅读更多关于 Play 默认使用的依赖注入和 Guice 框架的信息。 Guice wiki

    【讨论】:

    • 谢谢。您能否详细说明如何将依赖项注入到类实例中。
    • 流程实际上是依赖于DI框架。在 Guice 中,常见模式是 1. 定义一个模块(扩展 AbstractModule 的类),该模块定义类(接口)及其实现的绑定(也可以使用注释完成绑定),2. 为该模块创建一个注入器 val injector = Guice.createInjector(new YourModule())。 3. 向注入器询问特定的类实例injector.getInstance(classOf[Obj])。所以实例化由 Guice 处理。也可以看看Play docs for DI
    • 在 Play 中你通常不会自己创建注入器,但是模块是常用的。请注意,您需要在 Play config (application.conf) 中启用模块
    • 我不想在 Obj 的构造函数中注入 ServiceClient。我想我正在寻找的是如何在 Obj 类中进行 serviceClient 的字段注入。你能给出一些代码示例吗?谢谢。
    • 正如您定义的那样,@Inject var client: ServiceClient = _ 应该可以工作,但您仍然需要让 Guice 实例化 Obj,这可以通过将 Obj 注入控制器来完成。
    猜你喜欢
    • 1970-01-01
    • 2015-01-21
    • 2015-11-02
    • 2016-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-05
    • 2022-06-15
    相关资源
    最近更新 更多