Skip to content

DI Bag API / index / Builder

Interface: Builder<Entries extends Entry, Constraints extends NeedConstraint = never> ​

Defined in: di-bag.ts:413

An immutable, type-checked graph builder. Every operation returns a new builder. Create one with DiBagApi.createBuilder. The same builder value can Builder.buildContainer a container once its graph is complete, or Builder.buildModule a reusable module whose unmet dependencies become requirements the installing host must satisfy.

See ​

https://dany-fedorov.github.io/di-bag/agent/api-card.html#builder

Type Parameters ​

Type ParameterDescription
EntriesThe union of accepted provider entries, one per public key.
ConstraintsThe requirements, contributions and lifetime obligations that installed modules retain on this graph.

Properties ​

buildModule ​

ts
readonly buildModule: BuilderBuildModule<Entries, Constraints>;

Defined in: di-bag.ts:610

Seal this graph as a reusable module and select its public names and typed tokens. Unselected services stay private to each installation; unmet dependencies become requirements of the module. Installed modules nest: their private bindings and retained constraints are nested inside this module.

Param ​

options

exportedServiceKeys is a finite tuple of existing names or tokens, and may be empty. moduleLabel is optional; each installation names its private bindings <moduleLabel>/<key> in error messages, cycle paths, graphSnapshot(), and observer events.

Returns ​

An immutable module that can be renamed or installed in another builder.

Throws ​

DI_BAG_INVALID_ARGUMENT for a malformed options object or non-tuple selection or the label is not a non-empty string; DI_BAG_UNKNOWN_SERVICE_KEY for an absent name or token; DI_BAG_INVALID_TOKEN for a value that is not a genuine token; DI_BAG_WRONG_TOKEN_KIND when an exported token kind conflicts with this graph.

Example ​

ts
const orders = DiBag.createBuilder()
  .withServices({ repository: () => new Map<string, number>() })
  .withServices({ placeOrder: ({ repository }: { repository: Map<string, number> }) => (id: string) => repository.set(id, 1) })
  .buildModule({ exportedServiceKeys: ['placeOrder'], moduleLabel: 'orders' });
// Errors and graphSnapshot() name the private binding 'orders/repository'.
const app = DiBag.createBuilder().withInstalledModules([orders]).buildContainer();

withCollectionContribution ​

ts
readonly withCollectionContribution: BuilderWithCollectionContribution<Entries, Constraints>;

Defined in: di-bag.ts:508

Append a provider to the list of a collection token.

Param ​

options

collectionToken names the list; provider is a provider or plain factory whose output satisfies the token's item type.

Returns ​

A new builder preserving contribution order.

Throws ​

DI_BAG_INVALID_ARGUMENT for a malformed options object; DI_BAG_INVALID_TOKEN or DI_BAG_WRONG_TOKEN_KIND for a bad token or kind; DI_BAG_INVALID_PROVIDER for an invalid provider.

Example ​

ts
const toolsKey = Symbol('tools');
const tools = DiBag.createToken(toolsKey).forCollectionOf<string>();
const builder = DiBag.createBuilder().withCollectionContribution({ collectionToken: tools, provider: () => 'search' }).withCollectionContribution({ collectionToken: tools, provider: () => 'fetch' });

withInstalledModules ​

ts
readonly withInstalledModules: BuilderWithInstalledModules<Entries, Constraints>;

Defined in: di-bag.ts:558

Install sealed modules in list order, allocating fresh private bindings for each installation. Each module is checked against this builder plus the modules before it in the list. The installing host must provide every requirement that no module of the graph provides.

Param ​

modules

A finite list of modules whose public names collide neither with this builder nor with each other.

Returns ​

A new builder exposing only the selected exports of each module; contributions keep list order.

Throws ​

DI_BAG_INVALID_ARGUMENT when modules is not an array; DI_BAG_INVALID_MODULE for an element not made by buildModule; DI_BAG_DUPLICATE_SERVICE_KEY when an export name is already registered; DI_BAG_WRONG_TOKEN_KIND when an installed token kind conflicts with this graph. A rejected list changes nothing.

Example ​

ts
const greeting = DiBag.createBuilder().withServices({ greet: ({ name }: { name: string }) => `hello, ${name}` }).buildModule({ exportedServiceKeys: ['greet'] });
const app = DiBag.createBuilder().withInstalledModules([greeting]).withServices({ name: () => 'Ada' }).buildContainer();

withReplacedService ​

ts
readonly withReplacedService: BuilderWithReplacedService<Entries, Constraints>;

Defined in: di-bag.ts:530

Replace an existing binding with a compatible provider, selecting it by name, service token, collection token.

Param ​

serviceKey

One existing string-literal service name or typed token.

Param ​

provider

The replacement, checked against every surviving consumer.

Returns ​

A new builder with the replacement.

Throws ​

DI_BAG_UNKNOWN_SERVICE_KEY for an absent key; DI_BAG_INVALID_PROVIDER for an invalid provider; DI_BAG_WRONG_TOKEN_KIND when a retained token use conflicts with this graph.

Example ​

ts
const builder = DiBag.createBuilder().withServices({ clock: () => Date.now() }).withReplacedService('clock', () => 0);

withServiceAlias ​

ts
readonly withServiceAlias: BuilderWithServiceAlias<Entries, Constraints>;

Defined in: di-bag.ts:480

Add another lookup name for an existing service.

Param ​

options

aliasKey is a new string name or single-service token; targetServiceKey is the existing name or token whose canonical acquisition is reused.

Returns ​

A new builder; aliases add no cache or ownership of their own.

Throws ​

DI_BAG_INVALID_ARGUMENT for a malformed options object; DI_BAG_INVALID_TOKEN or DI_BAG_WRONG_TOKEN_KIND for a bad token or kind; DI_BAG_DUPLICATE_SERVICE_KEY when the alias key exists; DI_BAG_UNKNOWN_SERVICE_KEY for an absent named target.

Example ​

ts
const builder = DiBag.createBuilder().withServices({ clock: () => Date.now() }).withServiceAlias({ aliasKey: 'now', targetServiceKey: 'clock' });

withServices ​

ts
readonly withServices: BuilderWithServices<Entries, Constraints>;

Defined in: di-bag.ts:441

Add new string-named services. A factory declares its dependencies in the type of its one object parameter; destructure it or read dependencies.name, never spread it. Bind typed tokens separately with withTokenService.

Param ​

providersByName

A finite object whose own string keys are service names and whose values are providers or plain factories.

Returns ​

A new builder containing snapshots of the supplied providers.

Throws ​

DI_BAG_INVALID_ARGUMENT for a malformed object or DI_BAG_INVALID_PROVIDER for a malformed value; DI_BAG_DUPLICATE_SERVICE_KEY for a name already registered; DI_BAG_WRONG_TOKEN_KIND when a retained token use conflicts with this graph.

Example ​

ts
type Clock = { now(): number };
const builder = DiBag.createBuilder().withServices({ clock: (): Clock => ({ now: () => Date.now() }) }).withServices({ stamp: ({ clock }: { clock: Clock }) => clock.now() });

withTokenService ​

ts
readonly withTokenService: BuilderWithTokenService<Entries, Constraints>;

Defined in: di-bag.ts:461

Add the single service of a typed token.

Param ​

token

A new single-service token.

Param ​

provider

A provider or plain factory whose exposed output satisfies the token's service type.

Returns ​

A new builder retaining the provider's metadata, lifetime, dependencies, and ownership stages.

Throws ​

DI_BAG_INVALID_TOKEN or DI_BAG_WRONG_TOKEN_KIND for a bad token or kind; DI_BAG_DUPLICATE_SERVICE_KEY when the token already has a service; DI_BAG_INVALID_PROVIDER for an invalid provider.

Example ​

ts
const clockKey = Symbol('clock');
const clock = DiBag.createToken(clockKey).forService<{ now(): number }>();
const builder = DiBag.createBuilder().withTokenService(clock, () => ({ now: () => Date.now() }));

Methods ​

buildContainer() ​

ts
buildContainer(this: Builder<Entries, Constraints> & CheckDependencyCompleteness<RegistrationsFromEntries<Entries>> & CompleteConstraints<Constraints, RegistrationsFromEntries<Entries>> & CheckedLifetimes<RegistrationsFromEntries<Entries>, Constraints>): Container<RegistrationsFromEntries<Entries>, Constraints>;

Defined in: di-bag.ts:628

Finish a complete graph as a lazy container. The container owns what it acquires; close it when done.

Parameters ​

ParameterDescription
this-

Returns ​

A fresh container that owns the acquisitions it creates.

Throws ​

DI_BAG_CLASSIFIER_REQUIRED when a provider uses auto acquisition, the facade has no Promise classifier, and the host has no process.getBuiltinModule.

Example ​

ts
const app = DiBag.createBuilder().withServices({ greeting: () => 'hello' }).buildContainer();
await app.close();

verifyGraphAtCompileTime() ​

ts
verifyGraphAtCompileTime<Self extends Builder<Entries, Constraints>>(this: Self): CompositionReport<Self>;

Defined in: di-bag.ts:586

Report at the type level why this graph would not build; the runtime call does nothing. Write builder.verifyGraphAtCompileTime() satisfies void; so a rejected graph fails on that line with the complete message and details, instead of at the start of the builder expression.

Type Parameters ​

Type ParameterDescription
Self-

Parameters ​

ParameterDescription
this-

Returns ​

void for a buildable graph; otherwise the failure that buildContainer() would report.

Example ​

ts
const builder = DiBag.createBuilder().withServices({ greeting: () => 'hello' });
builder.verifyGraphAtCompileTime() satisfies void;

Ordinary services. Checked composition. Explicit ownership.