DI Bag API / index / Container
Interface: Container<ServiceRegistrations extends Registrations, Constraints extends NeedConstraint = never>
Defined in: di-bag.ts:114
A resolving container with lazy acquisition, caching, and independent resource ownership.
Create containers through DiBagApi.createBuilder followed by Builder.buildContainer, and make services ready ahead of use with Container.ensureServicesReady; the class is exported as a type and has no public constructor.
See
https://dany-fedorov.github.io/di-bag/agent/api-card.html#container
Type Parameters
| Type Parameter | Description |
|---|---|
ServiceRegistrations | The map from each public service name or token symbol to its provider. |
Constraints | The requirements, contributions and lifetime obligations that installed modules retain on this graph. |
Methods
close()
close(options?: CloseOptions): Promise<void>;Defined in: di-bag.ts:398
Close this container, drain in-flight work, and dispose owned resources once. Dependents are disposed before dependencies; remaining independent acquisitions use reverse acquisition order. Without options the promise waits for disposal however long it takes, and repeated calls return the same promise. With waitTimeoutMs or abortSignal, disposal starts the same way but the returned promise stops waiting when either fires; child and independent containers accept the same options. Close every derived container you create; a parent closes its live children, never independent containers.
Parameters
| Parameter | Description |
|---|---|
options? | An optional deadline and abort signal bounding the wait, not the disposal. |
Returns
The shared shutdown promise, or a bounded wait on it when options are given.
Throws
DiBagDisposalError (DI_BAG_DISPOSAL_FAILED) when one or more disposers fail after all disposal is attempted; DI_BAG_CLOSE_FAILED for other shutdown failures; DiBagCloseCancelledError (DI_BAG_CLOSE_TIMEOUT or DI_BAG_CLOSE_ABORTED) when the wait stops first, naming unfinished disposers in details.disposersStillRunning; DI_BAG_INVALID_ARGUMENT for malformed options.
Example
const container = DiBag.createBuilder().withServices({ value: () => 1 }).buildContainer();
await container.close({ waitTimeoutMs: 10_000, abortSignal: AbortSignal.timeout(15_000) });createChildContainer()
Call Signature
createChildContainer(options?: CreateChildContainerOptions<ServiceRegistrations, readonly [], Constraints>): Container<UnsharedAliases<ServiceRegistrations>, Constraints>;Defined in: di-bag.ts:278
Create a tracked child container with fresh ownership for unshared services. Share selected non-transient parent acquisitions through the optional options object. To replace services, pass selected keys and providers first, then the sharing options.
Parameters
| Parameter | Description |
|---|---|
options? | - |
Returns
A child owned by this container; closing the parent closes the child first.
Throws
DI_BAG_INVALID_ARGUMENT for malformed arguments; DI_BAG_CONFLICTING_SERVICE_SELECTION when one key is shared and replaced or a transient service is shared; DI_BAG_MISSING_REPLACEMENT_PROVIDER for a missing replacement provider; DI_BAG_UNKNOWN_SERVICE_KEY for an unknown selected key; DI_BAG_SINGLETON_REPLACEMENT when a selected inherited provider is singleton; DI_BAG_INVALID_TOKEN or DI_BAG_WRONG_TOKEN_KIND for a bad token or kind.
Example
const parent = DiBag.createBuilder().withServices({ request: DiBag.providerWithLifetime({
provider: () => ({ id: 'initial' }), lifetime: 'scoped:one-per-container',
}) }).buildContainer();
const child = parent.createChildContainer(['request'], { request: () => ({ id: 'child' }) });
const request = child.resolve('request');
await child.close();
await parent.close();Call Signature
createChildContainer<const SharedParentServiceKeys extends readonly unknown[]>(options: CreateChildContainerOptions<ServiceRegistrations, SharedParentServiceKeys, Constraints>): Container<ScopedAliases<ServiceRegistrations, ServiceRegistrations, SharedParentServiceKeys>, Constraints>;Defined in: di-bag.ts:281
Create a tracked child container with fresh ownership for unshared services. Share selected non-transient parent acquisitions through the optional options object. To replace services, pass selected keys and providers first, then the sharing options.
Type Parameters
| Type Parameter | Description |
|---|---|
SharedParentServiceKeys | - |
Parameters
| Parameter | Description |
|---|---|
options | - |
Returns
A child owned by this container; closing the parent closes the child first.
Throws
DI_BAG_INVALID_ARGUMENT for malformed arguments; DI_BAG_CONFLICTING_SERVICE_SELECTION when one key is shared and replaced or a transient service is shared; DI_BAG_MISSING_REPLACEMENT_PROVIDER for a missing replacement provider; DI_BAG_UNKNOWN_SERVICE_KEY for an unknown selected key; DI_BAG_SINGLETON_REPLACEMENT when a selected inherited provider is singleton; DI_BAG_INVALID_TOKEN or DI_BAG_WRONG_TOKEN_KIND for a bad token or kind.
Example
const parent = DiBag.createBuilder().withServices({ request: DiBag.providerWithLifetime({
provider: () => ({ id: 'initial' }), lifetime: 'scoped:one-per-container',
}) }).buildContainer();
const child = parent.createChildContainer(['request'], { request: () => ({ id: 'child' }) });
const request = child.resolve('request');
await child.close();
await parent.close();Call Signature
createChildContainer<const ReplacedServiceKeys extends readonly unknown[], ReplacementProviders extends OverrideFactoryContext<ServiceRegistrations, ReplacedServiceKeys, ReplacementProviders>, const SharedParentServiceKeys extends readonly unknown[] = readonly []>(replacedServiceKeys: ReplacedServiceKeys & Selection<ServiceRegistrations, Constraints, ReplacedServiceKeys, 'createChildContainer'>, replacementProviders: ReplacementProviders & ChildReplacementAdmission<ServiceRegistrations, ReplacedServiceKeys> & object & Record<SelectionKey<ReplacedServiceKeys[number]>, ProviderOrFactory> & Overrides<ServiceRegistrations, ReboundSelection<ServiceRegistrations, ReplacedServiceKeys, SelectedRegistrations<ReplacedServiceKeys, ReplacementProviders>>, ReplacedServiceKeys, 'createChildContainer'> & CheckDependencyCompatibility<OverrideRegistrations<ServiceRegistrations, ReboundSelection<ServiceRegistrations, ReplacedServiceKeys, SelectedRegistrations<ReplacedServiceKeys, ReplacementProviders>>>> & CheckDependencyCompleteness<OverrideRegistrations<ServiceRegistrations, ReboundSelection<ServiceRegistrations, ReplacedServiceKeys, SelectedRegistrations<ReplacedServiceKeys, ReplacementProviders>>>> & CheckedConstraints<Constraints, OverrideRegistrations<ServiceRegistrations, ReboundSelection<ServiceRegistrations, ReplacedServiceKeys, SelectedRegistrations<ReplacedServiceKeys, ReplacementProviders>>>> & CompleteConstraints<Constraints, OverrideRegistrations<ServiceRegistrations, ReboundSelection<ServiceRegistrations, ReplacedServiceKeys, SelectedRegistrations<ReplacedServiceKeys, ReplacementProviders>>>> & CheckedChildContainerLifetimes<NoInfer<ScopedAliases<OverrideRegistrations<ServiceRegistrations, ReboundSelection<ServiceRegistrations, ReplacedServiceKeys, SelectedRegistrations<ReplacedServiceKeys, ReplacementProviders>>>, ServiceRegistrations, SharedParentServiceKeys>>, NoInfer<ReboundSelection<ServiceRegistrations, ReplacedServiceKeys, SelectedRegistrations<ReplacedServiceKeys, ReplacementProviders>>>, WithoutExportObligations<Constraints, SelectionKey<ReplacedServiceKeys[number]>>>, options?: Pick<CreateChildContainerOptions<ServiceRegistrations, SharedParentServiceKeys, Constraints>, 'sharedParentServiceKeys'> & DisjointChildContainerSelection<ReplacedServiceKeys, SharedParentServiceKeys>): Container<ScopedAliases<OverrideRegistrations<ServiceRegistrations, ReboundSelection<ServiceRegistrations, ReplacedServiceKeys, SelectedRegistrations<ReplacedServiceKeys, ReplacementProviders>>>, ServiceRegistrations, SharedParentServiceKeys>, WithoutExportObligations<Constraints, SelectionKey<ReplacedServiceKeys[number]>>>;Defined in: di-bag.ts:284
Create a tracked child container with fresh ownership for unshared services. Share selected non-transient parent acquisitions through the optional options object. To replace services, pass selected keys and providers first, then the sharing options.
Type Parameters
| Type Parameter | Description |
|---|---|
ReplacedServiceKeys | - |
ReplacementProviders | - |
SharedParentServiceKeys | - |
Parameters
| Parameter | Description |
|---|---|
replacedServiceKeys | - |
replacementProviders | - |
options? | - |
Returns
A child owned by this container; closing the parent closes the child first.
Throws
DI_BAG_INVALID_ARGUMENT for malformed arguments; DI_BAG_CONFLICTING_SERVICE_SELECTION when one key is shared and replaced or a transient service is shared; DI_BAG_MISSING_REPLACEMENT_PROVIDER for a missing replacement provider; DI_BAG_UNKNOWN_SERVICE_KEY for an unknown selected key; DI_BAG_SINGLETON_REPLACEMENT when a selected inherited provider is singleton; DI_BAG_INVALID_TOKEN or DI_BAG_WRONG_TOKEN_KIND for a bad token or kind.
Example
const parent = DiBag.createBuilder().withServices({ request: DiBag.providerWithLifetime({
provider: () => ({ id: 'initial' }), lifetime: 'scoped:one-per-container',
}) }).buildContainer();
const child = parent.createChildContainer(['request'], { request: () => ({ id: 'child' }) });
const request = child.resolve('request');
await child.close();
await parent.close();createIndependentContainer()
Call Signature
createIndependentContainer(this: Container<ServiceRegistrations, Constraints> & CheckedLifetimes<UnsharedAliases<ServiceRegistrations>, Constraints>, options?: CreateIndependentContainerOptions<ServiceRegistrations, Constraints>): Container<UnsharedAliases<ServiceRegistrations>, Constraints>;Defined in: di-bag.ts:312
Create an independent container with fresh instances and no replacements. Pass no argument, undefined, or an empty options object.
Parameters
| Parameter | Description |
|---|---|
this | - |
options? | - |
Returns
A container with independent acquisition and ownership state.
Throws
DI_BAG_INVALID_ARGUMENT for malformed arguments.
Call Signature
createIndependentContainer<const ReplacedServiceKeys extends readonly unknown[], ReplacementProviders extends OverrideFactoryContext<ServiceRegistrations, ReplacedServiceKeys, ReplacementProviders>>(replacedServiceKeys: ReplacedServiceKeys & Selection<ServiceRegistrations, Constraints, ReplacedServiceKeys, 'createIndependentContainer'>, replacementProviders: ReplacementProviders & object & Record<SelectionKey<ReplacedServiceKeys[number]>, ProviderOrFactory> & Overrides<ServiceRegistrations, ReboundSelection<ServiceRegistrations, ReplacedServiceKeys, SelectedRegistrations<ReplacedServiceKeys, ReplacementProviders>>, ReplacedServiceKeys, 'createIndependentContainer'> & CheckDependencyCompatibility<OverrideRegistrations<ServiceRegistrations, ReboundSelection<ServiceRegistrations, ReplacedServiceKeys, SelectedRegistrations<ReplacedServiceKeys, ReplacementProviders>>>> & CheckDependencyCompleteness<OverrideRegistrations<ServiceRegistrations, ReboundSelection<ServiceRegistrations, ReplacedServiceKeys, SelectedRegistrations<ReplacedServiceKeys, ReplacementProviders>>>> & CheckedConstraints<Constraints, OverrideRegistrations<ServiceRegistrations, ReboundSelection<ServiceRegistrations, ReplacedServiceKeys, SelectedRegistrations<ReplacedServiceKeys, ReplacementProviders>>>> & CompleteConstraints<Constraints, OverrideRegistrations<ServiceRegistrations, ReboundSelection<ServiceRegistrations, ReplacedServiceKeys, SelectedRegistrations<ReplacedServiceKeys, ReplacementProviders>>>> & CheckedLifetimes<UnsharedAliases<OverrideRegistrations<ServiceRegistrations, ReboundSelection<ServiceRegistrations, ReplacedServiceKeys, SelectedRegistrations<ReplacedServiceKeys, ReplacementProviders>>>>, WithoutExportObligations<Constraints, SelectionKey<ReplacedServiceKeys[number]>>>): Container<UnsharedAliases<OverrideRegistrations<ServiceRegistrations, ReboundSelection<ServiceRegistrations, ReplacedServiceKeys, SelectedRegistrations<ReplacedServiceKeys, ReplacementProviders>>>>, WithoutExportObligations<Constraints, SelectionKey<ReplacedServiceKeys[number]>>>;Defined in: di-bag.ts:330
Create an independent container with fresh instances and checked replacements.
Type Parameters
| Type Parameter | Description |
|---|---|
ReplacedServiceKeys | - |
ReplacementProviders | - |
Parameters
| Parameter | Description |
|---|---|
replacedServiceKeys | - |
replacementProviders | - |
Returns
A container with independent acquisition and ownership state.
Throws
DI_BAG_INVALID_ARGUMENT for malformed arguments; DI_BAG_MISSING_REPLACEMENT_PROVIDER for a missing replacement provider; DI_BAG_UNKNOWN_SERVICE_KEY for an unknown selected key; DI_BAG_INVALID_PROVIDER for a malformed provider; DI_BAG_INVALID_TOKEN or DI_BAG_WRONG_TOKEN_KIND for a bad token or kind.
Example
const parent = DiBag.createBuilder().withServices({ clock: () => Date.now() }).buildContainer();
const independent = parent.createIndependentContainer(['clock'], { clock: () => 0 });
const now = independent.resolve('clock');
await independent.close();
await parent.close();ensureServicesReady()
ensureServicesReady<const K extends readonly unknown[]>(serviceKeys: K & Selection<ServiceRegistrations, Constraints, K, 'ensureServicesReady'>, options?: EnsureServicesReadyOptions): Promise<this>;Defined in: di-bag.ts:371
Make the listed services ready before continuing, then resolve to this same container. Each listed service is acquired now, with whatever its factory reads, and the call waits until it is ready; every other service stays lazy. List the services whose readiness you need before the next line runs, such as a database pool or a cache client. Works on a built container, a child container, and an independent container, and may be called again. A failed factory, an aborted signal, or an elapsed deadline closes this container: a child container closes only itself, never its parent or a service it borrows.
Type Parameters
| Type Parameter | Description |
|---|---|
K | - |
Parameters
| Parameter | Description |
|---|---|
serviceKeys | A finite tuple of existing names or typed tokens to wait for; an empty tuple is valid. |
options? | An optional abort signal, a deadline for the whole call, and a bound on how many listed keys are acquired at once. |
Returns
A promise for this container once every listed service is ready.
Throws
DiBagServiceReadinessError (DI_BAG_SERVICE_READINESS_FAILED) after this container has closed because a factory failed; DiBagServiceReadinessCancelledError (DI_BAG_SERVICE_READINESS_CANCELLED) promptly on abort or timeout, naming what was still pending; DI_BAG_INVALID_ARGUMENT for malformed keys or options, DI_BAG_UNKNOWN_SERVICE_KEY for an unknown key, and DI_BAG_INVALID_TOKEN or DI_BAG_WRONG_TOKEN_KIND for a bad token or kind, all before any factory runs and with this container left open; DI_BAG_CLOSING or DI_BAG_CLOSED after close(). Each arrives as a rejection.
Example
const container = await DiBag.createBuilder()
.withServices({ db: async () => ({ ping: () => true }) })
.buildContainer()
.ensureServicesReady(['db'], { totalTimeoutMs: 5_000 });graphSnapshot()
graphSnapshot(): GraphSnapshot;Defined in: di-bag.ts:257
Describe every resolvable binding and the dependency edges observed so far.
Returns
A frozen point-in-time graph snapshot without acquiring services.
Example
const container = DiBag.createBuilder().withServices({ greeting: () => 'hello' }).buildContainer();
const labels = container.graphSnapshot().bindings.map(binding => binding.bindingLabel);
await container.close();resolve()
resolve<K extends (keyof ServiceRegistrations & string) | TokenBase>(token: K & ([K] extends [string] ? unknown : SingleServiceTokenMember<ServiceRegistrations, K>)): ServicesOf<ServiceRegistrations>[SelectionKey<K> & keyof ServiceRegistrations];Defined in: di-bag.ts:146
Resolve a registered service, acquiring it lazily when needed. Scoped and singleton services are cached according to their lifetime; transient services create a new acquisition for each call. Promise-valued services keep their identity. An async factory's service is its Promise; nothing is awaited for you.
Type Parameters
| Type Parameter | Description |
|---|---|
K | - |
Parameters
| Parameter | Description |
|---|---|
token | An existing public string name or typed token. |
Returns
The service exposed by the selected provider.
Throws
DI_BAG_CLOSING or DI_BAG_CLOSED after close(); DI_BAG_INVALID_TOKEN, DI_BAG_WRONG_TOKEN_KIND, or DI_BAG_UNKNOWN_SERVICE_KEY for a bad selection; during acquisition DI_BAG_MISSING_DEPENDENCY, DI_BAG_DEPENDENCY_CYCLE, DI_BAG_LIFETIME_DEPENDENCY, DI_BAG_INVALID_DEPENDENCY_ACCESS, DI_BAG_STRUCTURAL_THENABLE, DI_BAG_INVALID_CLASSIFIER_RESULT, DI_BAG_INVALID_ACQUISITION_METADATA, DI_BAG_PLUGIN_VALIDATION, or the factory's own error.
Example
const container = DiBag.createBuilder().withServices({ greeting: () => 'hello' }).buildContainer();
const greeting: string = container.resolve('greeting');resolveCollection()
resolveCollection<T extends CollectionTokenBase>(token: T & CollectionTokenMember<Constraints, T>, ...invalid: [T] extends [never] ? [never] : []): readonly CollectionItem<T>[];Defined in: di-bag.ts:172
Resolve every contribution for a collection token as a fresh frozen list.
Type Parameters
| Type Parameter | Description |
|---|---|
T | - |
Parameters
| Parameter | Description |
|---|---|
token | The collection token to read. |
...invalid | - |
Returns
Contributions in declaration order, or an empty list.
Throws
DI_BAG_INVALID_TOKEN or DI_BAG_WRONG_TOKEN_KIND for a bad handle or kind; DI_BAG_CLOSING or DI_BAG_CLOSED after close begins; or a contribution's acquisition errors as listed for Container.resolve.
Example
const toolsKey = Symbol('tools');
const tools = DiBag.createToken(toolsKey).forCollectionOf<string>();
const container = DiBag.createBuilder().buildContainer();
const names: readonly string[] = container.resolveCollection(tools);serviceSnapshot()
Call Signature
serviceSnapshot<ServiceKey extends (keyof ServiceRegistrations & string) | TokenBase>(serviceKey: ServiceKey & ([ServiceKey] extends [string] ? unknown : SingleServiceTokenMember<ServiceRegistrations, ServiceKey>), ...invalid: [ServiceKey] extends [never] ? [never] : []): RegistrationSnapshot<ProviderRegistrationMetadata<ServiceRegistrations[SelectionKey<ServiceKey> & keyof ServiceRegistrations]>, ProviderAcquisitionMetadata<ServiceRegistrations[SelectionKey<ServiceKey> & keyof ServiceRegistrations]>>;Defined in: di-bag.ts:197
Inspect a service binding through any supported public key without resolving it.
Type Parameters
| Type Parameter | Description |
|---|---|
ServiceKey | - |
Parameters
| Parameter | Description |
|---|---|
serviceKey | The public service name or typed token to inspect. |
...invalid | - |
Returns
The service snapshot, or one snapshot per collection contribution.
Throws
DI_BAG_INVALID_TOKEN or DI_BAG_WRONG_TOKEN_KIND for a bad handle or kind.
Example
const container = DiBag.createBuilder().withServices({ greeting: () => 'hello' }).buildContainer();
const snapshot = container.serviceSnapshot('greeting');
await container.close();Call Signature
serviceSnapshot<CollectionToken extends CollectionTokenBase>(collectionToken: CollectionToken & CollectionTokenMember<Constraints, CollectionToken>, ...invalid: [CollectionToken] extends [never] ? [never] : []): readonly RegistrationSnapshot<object, readonly unknown[]>[];Defined in: di-bag.ts:220
Inspect every contribution to a collection without resolving it.
Type Parameters
| Type Parameter | Description |
|---|---|
CollectionToken | - |
Parameters
| Parameter | Description |
|---|---|
collectionToken | The typed collection token to inspect. |
...invalid | - |
Returns
One service snapshot per collection contribution.
Throws
DI_BAG_INVALID_TOKEN or DI_BAG_WRONG_TOKEN_KIND for a bad handle or kind.
Example
const handlersKey = Symbol('handlers');
const handlers = DiBag.createToken(handlersKey).forCollectionOf<() => void>();
const container = DiBag.createBuilder()
.withCollectionContribution({ collectionToken: handlers, provider: () => () => {} })
.buildContainer();
const snapshots = container.serviceSnapshot(handlers);
await container.close();Call Signature
serviceSnapshot<ServiceKey extends (keyof ServiceRegistrations & string) | TokenBase>(serviceKey: ServiceKey & ([
ServiceKey
] extends [string] ? unknown : [ServiceKey] extends [CollectionTokenBase] ? CollectionTokenMember<Constraints, ServiceKey> : SingleServiceTokenMember<ServiceRegistrations, ServiceKey>), ...invalid: [ServiceKey] extends [never] ? [never] : []): TokenBase extends ServiceKey ? RegistrationSnapshot<object, readonly unknown[]> | readonly RegistrationSnapshot<object, readonly unknown[]>[] : ServiceKey extends CollectionTokenBase ? readonly RegistrationSnapshot<object, readonly unknown[]>[] : RegistrationSnapshot<ProviderRegistrationMetadata<ServiceRegistrations[SelectionKey<ServiceKey> & keyof ServiceRegistrations]>, ProviderAcquisitionMetadata<ServiceRegistrations[SelectionKey<ServiceKey> & keyof ServiceRegistrations]>>;Defined in: di-bag.ts:224
Inspect a service binding through any supported public key without resolving it.
Type Parameters
| Type Parameter | Description |
|---|---|
ServiceKey | - |
Parameters
| Parameter | Description |
|---|---|
serviceKey | The public service name or typed token to inspect. |
...invalid | - |
Returns
The service snapshot, or one snapshot per collection contribution.
Throws
DI_BAG_INVALID_TOKEN or DI_BAG_WRONG_TOKEN_KIND for a bad handle or kind.
Example
const container = DiBag.createBuilder().withServices({ greeting: () => 'hello' }).buildContainer();
const snapshot = container.serviceSnapshot('greeting');
await container.close();