@jsonjoy.com/di
v18.28.0
Published
Lightweight dependency injection container with lifetimes, scopes, and lifecycle management
Downloads
175
Readme
@jsonjoy.com/di
Lightweight, dependency-free dependency injection (DI) container for Node.js and
the browser. It resolves, caches, and disposes service instances across a
parent–child container hierarchy, with support for singleton, scoped, and
transient lifetimes and automatic lifecycle management (start/stop/dispose).
Usage
Register services against typed tokens and resolve them from a container. Each
service receives the DI context (DiContext) as its first constructor argument
and resolves its own dependencies via ctx.make(token); any further constructor
arguments are the static arguments declared in the descriptor.
import {Container, Registry, Token, Descriptor, type DiContext} from '@jsonjoy.com/di';
const LoggerToken = Token.create<Logger>('Logger');
const ServiceToken = Token.create<Service>('Service');
class Logger {
constructor(_ctx: DiContext) {}
log(msg: string) {
console.log(msg);
}
}
class Service {
public readonly logger: Logger;
constructor(ctx: DiContext) {
this.logger = ctx.make(LoggerToken);
}
}
const registry = new Registry();
registry.set(LoggerToken, new Descriptor(Logger));
registry.set(ServiceToken, new Descriptor(Service));
const container = new Container(registry);
const service = container.make(ServiceToken);
service.logger.log('hello');
await container.dispose();Concepts
Token<T>— a typed identifier used to register and resolve a service.Descriptor<T>— describes how to construct a service: its constructor, static arguments,lifetime(singleton|scoped|transient), and ownership.Registry— a collection of token-to-descriptor registrations.Container— resolves and caches instances, manages scopes viacreateChild(), and disposes owned instances. ImplementsPrintable, so a container can be printed as a tree for debugging.
Lifetimes
singleton— one instance per container that owns the registration.scoped— one instance per child container (scope).transient— a fresh instance on every resolution.
Lifecycle
Services may implement IStartable, IStoppable, and IDisposable. The
container invokes start() on resolution and stop()/dispose() (in reverse
dependency order) when the container is disposed.
