Guides
Task-oriented documentation for common DiCaf workflows. Start with Getting Started if you are new to the library.
Table of contents
-
Getting Started — install DiCaf, create your first container, and resolve your first dependency.
-
Configuring the Container — all
DiCafconstructor options: default scope, lazy mode, profiles, scope validation, circular reference detection, parent containers, and metadata readers. -
Modules — organize bindings into reusable module functions, name them for debugging, write async modules, and create child containers.
-
Decorators — annotate classes with
@Injectable,@Configuration,@Provides, and all related decorators to declare dependencies without writing module functions. -
Factory Classes — use
@Configuration+@Providesto produce bindings from factory methods: third-party types, assembled values, and anything@Injectablecannot cover alone. -
Abstract Classes — register multiple implementations of an abstract class, inject all of them with
allOf, and select between them using@Named,@Primary, and@ConditionalOn. -
Interfaces — use symbol tokens as runtime keys for TypeScript interfaces, with the same injection patterns as abstract classes.
-
Collections — inject all bindings under a key as an array with
allOf(), or as a named map withmapped(). -
Object Injection — inject a group of dependencies as a single plain object using
object(), including nested specs and optional properties. -
Building Instances — use
build()for one-off instances andbuilder()for reusable compiled factories, both backed by container bindings. -
Functions — bind plain functions with
toFunction()to produce closures, plain objects, or objects with methods, with dependencies injected positionally. -
Factory — bind a raw factory function with
toFactory()to access the container directly at resolution time; useful for dynamic or conditional dependencies. -
Conditional Bindings — register implementations only when a predicate passes at init time: region flags, env vars, feature toggles, or presence of another binding.
-
Fallback Bindings — mark a binding as a last-resort default, active only when no other non-fallback binding is registered for the same key; the standard pattern for overridable library defaults.
-
Lazy Bindings — defer construction of a binding until its first resolution; reduce startup time for expensive services and break circular dependency cycles.
-
Profiles — group bindings under named profiles (
test,production,eu) and activate them declaratively via the containerprofilesoption. -
Mixing Scopes — safely inject shorter-lived dependencies into longer-lived components using
provide()andProvider<T>; scope validation options. -
Async Bindings — bind keys to async factories using
toAsyncFactory(),@UseAsyncFactory, or@Async+@Provides; constraints and ordering rules. -
Testing — write isolated tests with
TestContainer: override bindings, focus on a dependency subtree, drop async bindings, and snapshot the global decorator registry. -
Scanning Files — use
scan()to auto-import all decorated source files in a directory, eliminating manual import lists in large codebases. -
Dependency Graph — build and render the container's dependency graph as text, Markdown, Mermaid, DOT, or JSON.