そのような依存性注入を提供するのは難しいです。上記の例のほとんどでは、クラスがインスタンス化される場所の近くに暗黙を作成する必要があります。
私が思いつくことができる最も近いものは次のとおりです。
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
}
HereE
は別のファイルで定義され、 のインスタンスを作成しますC
。(経由で)に依存するそのドキュメントD
に渡される必要があります。E
E
D
C