提供这种类型的依赖注入很棘手。上述大多数示例都要求您在实例化类的位置附近创建隐式。
我能想到的最接近的是:
class A(implicit b:B, c:C)
class B(implicit d:D)
class C(implicit d:D)
trait D { //the interface
def x:Unit
}
object Implicits {
implicit def aFactory:A = new A
implicit lazy val bInstance:B = new B
implicit def cFactory:C = new C
implicit def dFactory:D = new D {
def x:Unit = {/* some code */}
}
}
然后在你的代码中你像这样使用它:
import Implicits._
object MyApplication {
def main(args: Array[String]):Unit = {
val a = new A
}
}
如果您(例如)在测试时需要能够指定不同的版本,您可以执行以下操作:
import Implicits._
object MyApplication {
// Define the actual implicits
Implicits.module = new Module {
import Implicits._
def a = new A
lazy val b = new B
def c = new C
def d = new D {
def x = println("x")
}
}
def main(args: Array[String]):Unit = {
val a = new A // or val a = implicitly[A]
}
}
// The contract (all elements that you need)
trait Module {
def a: A
def b: B
def c: C
def d: D
}
// Making the contract available as implicits
object Implicits {
var module: Module = _
implicit def aFactory:A = module.a
implicit def bFactory:B = module.b
implicit def cFactory:C = module.c
implicit def dFactory:D = module.d
}
这将允许您在任何文件中简单地导入 Implicits._ 并提供与原始问题中的工作流程类似的工作流程。
然而,在大多数情况下,我不会使用这种策略。我只会在创建实例的类中提供隐式:
object MyApplication {
implicit def a: A = new A
implicit lazy val b: B = new B
implicit def c: C = new C
implicit def d: D = new D {
def x: Unit = println("x")
}
def main(args: Array[String]): Unit = {
val a = implicitly[A]
val e = new E
}
}
class E(implicit d:D) {
new C
}
这里E
是在另一个文件中定义并创建一个C
. 我们需要D
传递给依赖于(via )E
的文档并与其一起传递。E
D
C