Scoped
Isolate State Per Request or Page
Scoped lifetime gives each scope its own instance. Use container.extend() to create a child scope when a request, page, conversation, or test needs isolated state while still sharing root singletons.
Creating a Scope With container.extend()
Call root.extend() to create a child container. Services marked LoadAs.Scoped get fresh instances in each child. Singletons from the root are still shared.
import createContainer, { Component, Inject, LoadAs } from "@noego/ioc";
@Component({ scope: LoadAs.Scoped })
export class RequestState {
userId: string | null = null;
}
@Component({ scope: LoadAs.Scoped })
export class CurrentUserWriter {
constructor(
@Inject(RequestState) private state: RequestState,
) {}
setUser(userId: string): void {
this.state.userId = userId;
}
}
const root = createContainer();
const requestScope = root.extend();
const writer = await requestScope.instance(CurrentUserWriter);Scope Inheritance
Child containers inherit all registrations from their parent. You can override any registration in a child container without affecting the parent or siblings. This is how test mocks work — register a fake on the test's child container, and the real container tree is untouched.
Rules
- Use Scoped for request, page, user, conversation, or test-case state.
- Scoped instances are isolated to one child container created via container.extend().
- Root singletons remain shared across scopes — they are not re-created.
- Pass runtime values to scoped classes via Parameter tokens (see Parameters page).
- Dispose scoped containers when the request or page completes to free memory.