【问题标题】:Using Guice annotations in Play (Scala)在 Play (Scala) 中使用 Guice 注释
【发布时间】:2016-04-27 12:35:32
【问题描述】:

想象一个 B 类如下:

class B @Inject() (wsClient: WSClient) {
  ...
}

然后在另一个类A中,我需要实例化B:

class A {
  val b = new B()
}

它会抱怨说我没有在构造函数中指定 wsClient。 解决此问题的一种方法是修改 A :

class A @Inject() (wsClient: WSClient) {
  val b = new B(wsClient)
}

我也可以在我的 B 类中添加一个隐式。但在这两种情况下,我似乎都非常错误地发送这样的依赖项......

我怎样才能以更优雅的方式做到这一点?

【问题讨论】:

    标签: java scala playframework guice


    【解决方案1】:

    做 DI 的全部意义在于拥有inversion of control。您的绑定决定了应用程序的构建方式,而不是应用程序中的类负责它们自己的控制流。

    val b = new B(wsClient) 行违反了这一原则,因为类负责知道它应该如何构成自己,而不是由 DI 框架负责。

    class B @Inject() (ws: WSClient){}
    
    class A @Inject() (b: B) // extends B
    {} 
    

    正如@zoltan 所暗示的,将 B 注入 A 将是解决问题的正确方法。

    【讨论】:

    • 通过一些操作,我如何在我的 A 类中访问 ws ? b.ws 不行,是不是说我需要绑定到class B里面?
    • 如果 A 需要 ws 则将其注入 A
    • 那么我必须在 A 和 B 中复制 @Inject() (ws: WSClient) 尽管将 B 注入 A ?
    • A 对 B 的依赖不应该是对 WS 的传递依赖。 A 对 B 执行的任何操作都应该独立于 B 注入 WS 的事实
    【解决方案2】:

    为什么不将B 注入A

    class A @Inject() (b: B)
    

    如果你的类 B 需要是一个单例,只需用 javax.inject.Singleton 注释它。

    【讨论】:

    • 我明白了,这解决了一个问题。但是,继承也会出现同样的问题,如果 A 扩展 B,我将不得不注入 A 并传递所有注入 B 的 deps 呢?
    猜你喜欢
    • 1970-01-01
    • 2019-08-16
    • 2016-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    相关资源
    最近更新 更多