Cookbook

Inner Classes and Path-Dependent Types

To instantiate path-dependent types via constructor, their prefix type must be present in the object graph:

import distage._

trait Path {
  class A
  class B
}

val path = new Path {}
// path: AnyRef with Path = repl.Session$App0$$anon$1@349c03d1

val module = new ModuleDef {
  make[path.A]
  make[path.type].from[path.type](path: path.type)
}
// module: AnyRef with ModuleDef = Set(SingletonBinding({type.repl.Session.App0.path.A},TypeImpl(repl.Session.App0.path.A),Set(),(cookbook.md:24)), SingletonBinding({type.repl.Session.App0.<refinement>.type},ProviderImpl(repl.Session.App0.<refinement>.type,com.github.pshirshov.izumi.distage.model.providers.ProviderMagnet$$$Lambda$12192/1414652283@22b8efe7(): repl.Session.App0.<refinement>.type),Set(),(cookbook.md:25)))

The same applies to type projections:

val module1 = new ModuleDef {
  make[Path#B]
  make[Path].from(new Path {})
}
// module1: AnyRef with ModuleDef = Set(SingletonBinding({type.repl.Session.App0.Path},ProviderImpl(repl.Session.App0.Path,com.github.pshirshov.izumi.distage.model.providers.ProviderMagnet$$$Lambda$12192/1414652283@5224805(): repl.Session.App0.Path),Set(),(cookbook.md:34)), SingletonBinding({type.repl.Session.App0.Path#B},TypeImpl(repl.Session.App0.Path#B),Set(),(cookbook.md:33)))

Function and instance bindings and also compile-time mode in distage-static module do not require the type prefix:

val module2 = new ModuleDef {
  make[Path#B].fromValue {
    val path = new Path {}
    new path.B
  }
}
// module2: AnyRef with ModuleDef = Set(SingletonBinding({type.repl.Session.App0.Path#B},InstanceImpl(path.B,repl.Session$App0$Path$B@375f6821),Set(),(cookbook.md:42)))

Depending on Locator

Classes can depend on the Locator (container of the final object graph):

import distage._

class A(all: LocatorRef) {
  def c = all.get.get[C]
}
class B
class C

val module = new ModuleDef {
  make[A]
  make[B]
  make[C]
}

val locator = Injector().produce(module)

assert(locator.get[A].c eq locator.get[C]) 

Locator contains metadata about the plan and the bindings from which it was ultimately created:

// Plan that created this locator
val plan: OrderedPlan = locator.plan

// Bindings from which the Plan was built
val moduleDef: ModuleBase = plan.definition