Skip to main content

Factories


Factory

type Factory<T> = (ctx: ResolutionContext) => T

A synchronous factory function. Used with toFactory() and @UseFactory.

di.bind(Logger).toFactory(ctx => {
const config = ctx.container.get(AppConfig)
return new ConsoleLogger(config.logLevel)
})
@Injectable()
@UseFactory(ctx => new ConsoleLogger(ctx.container.get(AppConfig)))
class Logger { ... }

AsyncFactory

type AsyncFactory<T> = (ctx: ResolutionContext) => Promise<T>

An async factory function. Used with toAsyncFactory(), @UseAsyncFactory, and @Async + @Provides inside @Configuration classes.

DiCaf awaits the promise during init() — by the time container.get() is called, the instance is already resolved.

Constraints:

  • Scope must be singleton or refresh. Transient and request scopes are not allowed.
  • Always eager — instantiated during init() regardless of lazy configuration.
  • Property injection (@InjectMember) and method injection (@InjectMethod) are not supported.
// Fluent API
di.bind(DatabasePool).toAsyncFactory(async ctx => {
const cfg = ctx.container.get(AppConfig)
return createPool(cfg.databaseUrl)
})
// Class decorator
@UseAsyncFactory(async ctx => {
const cfg = ctx.container.get(AppConfig)
return fetchConfig(cfg.vaultUrl)
})
@Injectable()
class RemoteConfig {}
// @Configuration method
@Configuration([AppConfig])
class InfraConfig {
constructor(private readonly config: AppConfig) {}

@Async()
@Provides(DatabasePool)
async databasePool(): Promise<DatabasePool> {
return createPool(this.config.databaseUrl)
}
}

For a task-oriented walkthrough, see the Async Bindings guide.


ResolutionContext

Passed to every factory and interceptor. Gives access to the container and the binding being resolved.

PropertyDescription
containerThe container. Use it to resolve other dependencies inside the factory.
keyThe key being resolved.
bindingThe full Binding descriptor for the current resolution.
di.bind(Greeter).toFactory(ctx => {
const name = ctx.container.get<string>('app.name')
const binding = ctx.binding
return new Greeter(name)
})