Skip to main content

Options

Constructor options for the DiCaf container.

import { DiCaf } from '@caffeine-projects/dicaf'
import type { Options } from '@caffeine-projects/dicaf'

const di = new DiCaf(options: Partial<Options>)

All fields are optional. Omitting them produces the defaults shown below.


Fields

profiles

profiles?: Identifier[]

Default: []

The set of active profiles. A binding annotated with @Profile('name') is registered only when 'name' appears in this array. Bindings with no @Profile annotation are always registered.

const di = new DiCaf({ profiles: ['production'] })

See the Profiles guide.


defaultScopeId

defaultScopeId?: Identifier

Default: Scopes.SINGLETON

Scope applied to bindings that do not explicitly declare one via @Lifetime() or .scope().

import { Scopes } from '@caffeine-projects/dicaf'

const di = new DiCaf({ defaultScopeId: Scopes.TRANSIENT })

Built-in identifiers: Scopes.SINGLETON, Scopes.TRANSIENT, Scopes.REFRESH, Scopes.REQUEST. See the Scopes reference.


lazy

lazy?: boolean

Default: false

When true, construction of eager-by-default bindings (singleton, container, refresh) is deferred to the first get() call instead of running during init().

Individual bindings override this with @Lazy() / @Lazy(false) or .lazy() / .lazy(false).

Priority (highest first):

  1. Binding-level @Lazy() / .lazy()
  2. This option
  3. Scope default
const di = new DiCaf({ lazy: true })
await di.init()
// nothing constructed yet

di.get(SomeService) // constructed here

See the Lazy guide.


parent

parent?: Container

Default: undefined

A parent container. When a key cannot be resolved in the current container, resolution falls through to the parent automatically.

Prefer container.newChild() over passing parent directly — newChild() copies container-scoped bindings and post-processors automatically.

const root = new DiCaf()
await root.init()

const child = root.newChild()
// child falls back to root for unregistered keys
await child.init()

checks

checks?: {
scopes?: ScopeCheckMode
circularReferences?: boolean
}

Validation checks applied during init().

checks.scopes

type ScopeCheckMode = 'compatible-scopes-only' | 'no-mix' | 'off'

Default: 'compatible-scopes-only'

Controls scope compatibility validation.

ModeBehaviour
'compatible-scopes-only'Durable scopes (singleton, container) cannot depend directly on shorter-lived scopes (transient, request). Reverse is allowed.
'no-mix'Every dependency in a chain must share the exact same scope as its consumer.
'off'Scope validation disabled.

'compatible-scopes-only' catches the most common mistake — a singleton holding a transient reference — without blocking valid mixed-scope designs that use provide().

const di = new DiCaf({ checks: { scopes: 'no-mix' } })

checks.circularReferences

circularReferences?: boolean

Default: true

When true, the container performs a graph traversal during init() and throws ErrCircularDependency if a cycle is detected. Disable only when you are intentionally breaking cycles with @Lazy().

const di = new DiCaf({ checks: { circularReferences: false } })

decorators

decorators?: boolean

Default: true

When true, the container calls autoWire() in its constructor, registering all @Injectable-decorated classes found in the global decorator registry at construction time.

Set to false for fully manual containers with no decorators:

const di = new DiCaf({ decorators: false })

di.bind(Logger).toSelf()
di.bind(UserService).toClass(UserService, [Logger])

await di.init()

metadataReader

metadataReader?: MetadataReader

Default: undefined

type MetadataReader = (key: Key) => Partial<Binding>

A function called for every binding at registration time. Its return value is merged into the binding, allowing external metadata sources (config files, environment variables) to override defaults without decorators.

const di = new DiCaf({
metadataReader: key => {
if (key === DbConnection) {
return { lazy: true }
}
return {}
},
})

Summary

FieldTypeDefault
profilesIdentifier[][]
defaultScopeIdIdentifierScopes.SINGLETON
lazybooleanfalse
parentContainerundefined
checks.scopesScopeCheckMode'compatible-scopes-only'
checks.circularReferencesbooleantrue
decoratorsbooleantrue
metadataReaderMetadataReaderundefined