score:0

Accepted answer

I suppose one approach is to have the outer service layer maintain an instance of the inner service layer, define the types in terms of that instance, and then assign the API's service members through the service member of the outer layer:

// interfaces

trait API {
  lazy val serviceA: serviceB.serviceA.type = serviceB.serviceA
  val serviceB: ServiceB[_ <: ServiceA]
  def op_API: Unit = serviceA.op_A(serviceB.op_B)
}

trait ServiceA {
  type X
  def op_A(x: X): Unit
}

trait ServiceB[A <: ServiceA] {
  val serviceA: A
  def op_B: serviceA.X
}

// implementations

object API_Impl extends API {
  val serviceB = ServiceB_Impl
}

object ServiceA_Impl extends ServiceA {
  type X = String
  def op_A(x: String): Unit = println(x)
}

object ServiceB_Impl extends ServiceB[ServiceA_Impl.type] {
  val serviceA = ServiceA_Impl
  def op_B: String = "test"
}

Related Query

More Query from same tag