Configuration Registries
Named configuration maps are modeled through tokenized providers.
Registry-by-Token Pattern
src/config-registry.ts
enum EEnvironment {
DEV = "dev",
PROD = "prod",
}
const ConfigMapToken = createToken<Record<string, { apiUrl: string }>>("ConfigMap");
const EnvironmentToken = createToken<EEnvironment>("Environment");
const RuntimeConfigToken = createToken<{ apiUrl: string }>("RuntimeConfig");
container.register({
provide: ConfigMapToken,
useValue: {
dev: { apiUrl: "http://localhost:3000" },
prod: { apiUrl: "https://api.example.com" },
},
});
container.register({ provide: EnvironmentToken, useValue: EEnvironment.DEV });
container.register({
provide: RuntimeConfigToken,
deps: [ConfigMapToken, EnvironmentToken],
useFactory: (configs, env) => configs[env],
});Benefits
- Keeps configuration strongly typed.
- Makes environment selection explicit and testable.
- Avoids hidden globals and static registries.
- Works naturally with scopes and lifecycle hooks.
Scoped Registry Pattern
Request-scoped data sets can be registered as scoped values:
src/request-context.ts
scope.register({
provide: RequestContextToken,
lifecycle: EDependencyLifecycle.SCOPED,
useValue: { requestId, tenantId },
});Last updated on