Packages

package definition

Ordering
  1. Alphabetic
Visibility
  1. Public
  2. Protected

Package Members

  1. package dsl

Type Members

  1. final case class Activation(activeChoices: Map[Axis, AxisValue]) extends AnyVal with Product with Serializable
  2. trait Axis extends AnyRef
  3. sealed trait Binding extends AnyRef
  4. sealed trait BindingTag extends AnyRef

    An attachment that can be added to a binding using its .tagged method

  5. trait BootstrapContextModule extends BootstrapModule
  6. trait BootstrapContextModuleDef extends BootstrapContextModule with ModuleDefDSL
  7. trait BootstrapModule extends ModuleBase
  8. trait BootstrapModuleDef extends BootstrapModule with ModuleDefDSL
  9. trait DIResource[+F[_], Resource] extends DIResourceBase[F, Resource]

    DIResource is a class that captures the effectful allocation of a resource, along with its finalizer.

    DIResource is a class that captures the effectful allocation of a resource, along with its finalizer. This can be used to wrap expensive resources.

    Resources can be created using DIResource.make:

    def open(file: File): DIResource[IO, BufferedReader] =
      DIResource.make(IO { new BufferedReader(new FileReader(file)) })(in => IO { in.close() })

    Using inheritance from DIResource:

    final class BufferedReaderResource(file: File)
      extends DIResource[IO, BufferedReader] {
        val acquire = IO { new BufferedReader(new FileReader(file)) }
        def release(in: BufferedReader) = IO { in.close() }
      }

    Using constructor-based inheritance from DIResource.Make, DIResource.LiftF, etc:

    final class BufferedReaderResource(file: File)
      extends DIResource.Make[IO, BufferedReader](
        acquire = IO { new BufferedReader(new FileReader(file)) },
        release = in => IO { in.close() },
      }

    Or by converting an existing cats.effect.Resource or a zio.ZManaged. Use DIResource.fromCats, DIResource.DIResourceCatsSyntax#toCats and DIResource.fromZIO, DIResource.DIResourceZIOSyntax#toZIO to convert back and forth.

    Usage is done via use:

    open(file1).use { in1 =>
      open(file2).use { in2 =>
        readFiles(in1, in2)
      }
    }

    DIResources can be combined into a larger resource via DIResourceBase.flatMap:

    val res: DIResource[IO, (BufferedReader, BufferedReader)] =
      open(file1).flatMap { in1 =>
       open(file2).flatMap { in2 =>
         IO.pure(in1 -> in2)
       }
     }

    Nested resources are released in reverse order of acquisition. Outer resources are released even if an inner use or release fails.

    DIResource can be used in non-FP context with DIResource.Simple it can also mimic Java's initialization-after-construction with DIResource.Mutable

    Use DIResource's to specify lifecycles of objects injected into the object graph.

    import distage.{DIResource, ModuleDef, Injector}
    import cats.effect.IO
    
    class DBConnection
    class MessageQueueConnection
    
    val dbResource = DIResource.make(IO { println("Connecting to DB!"); new DBConnection })(_ => IO(println("Disconnecting DB")))
    val mqResource = DIResource.make(IO { println("Connecting to Message Queue!"); new MessageQueueConnection })(_ => IO(println("Disconnecting Message Queue")))
    
    class MyApp(db: DBConnection, mq: MessageQueueConnection) {
      val run = IO(println("Hello World!"))
    }
    
    val module = new ModuleDef {
      make[DBConnection].fromResource(dbResource)
      make[MessageQueueConnection].fromResource(mqResource)
      make[MyApp]
    }
    
    Injector().produceFGet[IO, MyApp](module)
      .use(_.run())
      .unsafeRunSync()

    Will produce the following output:

    Connecting to DB!
    Connecting to Message Queue!
    Hello World!
    Disconnecting Message Queue
    Disconnecting DB

    The lifecycle of the entire object graph is itself expressed with DIResource, you can control it by controlling the scope of .use or by manually invoking DIResourceBase.acquire and DIResourceBase.release.

    See also

    ModuleDef.fromResource: izumi.distage.model.definition.dsl.ModuleDefDSL.MakeDSLBase#fromResource cats.effect.Resource: https://typelevel.org/cats-effect/datatypes/resource.html zio.ZManaged: https://zio.dev/docs/datatypes/datatypes_managed

  10. trait DIStageAnnotation extends Annotation with StaticAnnotation
  11. final class Id extends Annotation with DIStageAnnotation

    Annotation for summoning named instances.

    Annotation for summoning named instances.

    Example:

    val module = new ModuleDef {
      make[Int].named("three").from(3)
      make[Int].named("five").from(5)
    }
    
    Injector().produce(module).run {
      (five: Int @Id("five"), three: Int @Id("three") =>
        assert(5 == five)
        assert(3 == three)
    }
  12. sealed trait ImplDef extends AnyRef
  13. trait LocatorDef extends AbstractLocator with AbstractBindingDefDSL[BindDSL, BindDSLUnnamedAfterFrom, SetDSL]
  14. trait Module extends ModuleBase
  15. trait ModuleBase extends ModuleBaseInstances
  16. trait ModuleDef extends Module with ModuleDefDSL

    DSL for defining module Bindings.

    DSL for defining module Bindings.

    Example:

    class Program[F[_]: TagK: Monad] extends ModuleDef {
      make[TaglessProgram[F]]
    }
    
    object TryInterpreters extends ModuleDef {
      make[Validation.Handler[Try]].from(tryValidationHandler)
      make[Interaction.Handler[Try]].from(tryInteractionHandler)
    }
    
    // Combine modules into a full program
    val TryProgram = new Program[Try] ++ TryInterpreters

    Singleton bindings:

    • make[X] = create X using its constructor
    • make[X].from[XImpl] = bind X to its subtype XImpl using XImpl's constructor
    • make[X].from(myX) = bind X to an already existing instance myX
    • make[X].from { y: Y => new X(y) } = bind X to an instance of X constructed by a given Provider function
    • make[X].named("special") = bind a named instance of X. It can then be summoned using Id annotation.
    • make[X].using[X]("special") = bind X to refer to another already bound named instance at key [X].named("special")
    • make[X].fromEffect(X.create[F]: F[X]) = create X using a purely-functional effect X.create in F monad
    • make[X].fromResource(X.resource[F]: Resource[F, X]) = create X using a Resource specifying its creation and destruction lifecycle

    Set bindings:

    • many[X].add[X1].add[X2] = bind a Set of X, and add subtypes X1 and X2 created via their constructors to it. Sets can be bound in multiple different modules. All the elements of the same set in different modules will be joined together.
    • many[X].add(x1).add(x2) = add *instances* x1 and x2 to a Set[X]
    • many[X].add { y: Y => new X1(y).add { y: Y => X2(y) } = add instances of X1 and X2 constructed by a given Provider function
    • many[X].named("special").add[X1] = create a named set of X, all the elements of it are added to this named set.
    • many[X].ref[XImpl] = add a reference to an already **existing** binding of XImpl to a set of X's
    • many[X].ref[X]("special") = add a reference to an **existing** named binding of X to a set of X's

    Tags:

    • make[X].tagged("t1", "t2) = attach tags to X's binding.
    • many[X].add[X1].tagged("x1tag") = Tag a specific element of X. The tags of sets and their elements are separate.
    • many[X].tagged("xsettag") = Tag the binding of empty Set of X with a tag. The tags of sets and their elements are separate.

    Includes:

    • include(that: ModuleDef) = add all bindings in that module into this module
    See also

    TagK

    Id

    ModuleDefDSL

  17. trait ModuleMake[T <: ModuleBase] extends Aux[T, T]
  18. final class With[T] extends Annotation with DIStageAnnotation

    This annotation lets you choose a more specific implementation for a result of factory method other than its return type.

    This annotation lets you choose a more specific implementation for a result of factory method other than its return type.

    Example:

    trait Actor {
      def id: UUID
    }
    
    trait ActorFactory {
      @With[ActorImpl]
      def newActor(id: UUID): Actor
    }
    
    class ActorImpl(val id: UUID, someDependency: SomeDependency) extends Actor
    class SomeDependency
    
    val module = new ModuleDef {
      make[ActorFactory]
      // generated factory implementation:
      //
      // make[ActorFactory].from {
      //  (someDependency: SomeDependency) =>
      //    new ActorFactory {
      //      override def newActor(id: UUID): Actor = {
      //        new ActorImpl(id, someDependency)
      //      }
      //    }
      // }
    }
    See also

    Auto-Factories

  19. final class impl extends Annotation with DIStageAnnotation

    An optional, documentation-only annotation conveying that an abstract class or a trait is the 'actual' implementation of its supertypes and will be bound later in DI with izumi.distage.constructors.TraitConstructor or izumi.distage.constructors.FactoryConstructor

    An optional, documentation-only annotation conveying that an abstract class or a trait is the 'actual' implementation of its supertypes and will be bound later in DI with izumi.distage.constructors.TraitConstructor or izumi.distage.constructors.FactoryConstructor

    Abstract classes or traits without obvious concrete subclasses may hinder the readability of a codebase, if you still want to use them to avoid writing the full constructor, you may use this annotation to aid the reader in understanding your intentions.

    @impl abstract class Impl(
      pluser: Pluser
    ) extends PlusedInt
    See also

    Auto-Traits

    Auto-Factories

Value Members

  1. object Activation extends Serializable
  2. object Axis
  3. object Binding
  4. object BindingTag
  5. object Bindings
  6. object BootstrapContextModule
  7. object BootstrapModule
  8. object DIResource
  9. object ImplDef
  10. object LocatorDef
  11. object Module
  12. object ModuleBase
  13. object ModuleBaseInstances
  14. object ModuleMake
  15. object StandardAxis

Ungrouped