Skip to main content

Request Scope Manager

Accessed via container.requestScopeManager. Controls REQUEST-scoped bindings — one instance per asynchronous execution context.

REQUEST scope relies on Node.js AsyncLocalStorage and is only available in Node.js environments.


RequestScopeManager

interface RequestScopeManager {
run<T>(fn: () => T | Promise<T>): Promise<T>
setStorage(storage: RequestScopeStorage): void
}

run

run<T>(fn: () => T | Promise<T>): Promise<Awaited<T>>

Starts a new request scope context and runs fn inside it. All REQUEST-scoped bindings resolved within the callback — at any depth — return the same instance for the duration of the call. Always returns a Promise that resolves after all request-scoped instances are destroyed (including any @PreDestroy hooks). Await it when cleanup ordering matters.

app.use(async (req, res, next) => {
await container.requestScopeManager.run(() => next())
})

Nested run() calls are not supported. Calling run() while a scope block is already active throws ErrIllegalScopeState.

Accessing a REQUEST-scoped binding outside of a run() block throws ErrOutOfScope.

setStorage

setStorage(storage: RequestScopeStorage): void

Replaces the underlying storage strategy. DiCaf uses AsyncLocalStorage internally by default. Call setStorage() only when you need to substitute a custom implementation — for example, in environments where AsyncLocalStorage is not available or when using a test double.

setStorage() must be called before the first run(). Calling run() with no storage set throws ErrNoRequestStorageSet.


RequestScopeStorage

interface RequestScopeStorage<T = any> {
run<R>(context: T, fn: () => R): R
getStore(): T | undefined
}

The storage contract used by the request scope. It mirrors the Node.js AsyncLocalStorage API, so an AsyncLocalStorage instance can be passed directly:

import { AsyncLocalStorage } from 'node:async_hooks'

container.requestScopeManager.setStorage(new AsyncLocalStorage())

See Request scope for full scope semantics and @Lifetime to mark a binding as request-scoped.