Lightweight dependency injection container for JavaScript/TypeScript
—
Core container interface providing comprehensive dependency registration, resolution, and lifecycle management with support for hierarchical child containers and resource disposal.
Pre-configured global container instance ready for immediate use.
/**
* Global dependency container instance
* Pre-created container available for immediate dependency registration and resolution
*/
const container: DependencyContainer;Usage Examples:
import { container } from "tsyringe";
// Register dependencies
container.register("ApiUrl", { useValue: "https://api.example.com" });
container.registerSingleton(DatabaseService);
// Resolve dependencies
const apiUrl = container.resolve<string>("ApiUrl");
const dbService = container.resolve(DatabaseService);Register dependencies using various provider types and configuration options.
/**
* Register a dependency with flexible provider options
* Multiple overloads support different provider types
*/
register<T>(token: InjectionToken<T>, provider: ValueProvider<T>): DependencyContainer;
register<T>(token: InjectionToken<T>, provider: FactoryProvider<T>): DependencyContainer;
register<T>(token: InjectionToken<T>, provider: TokenProvider<T>, options?: RegistrationOptions): DependencyContainer;
register<T>(token: InjectionToken<T>, provider: ClassProvider<T>, options?: RegistrationOptions): DependencyContainer;
register<T>(token: InjectionToken<T>, provider: constructor<T>, options?: RegistrationOptions): DependencyContainer;
/**
* Register a singleton dependency (shared instance across container)
*/
registerSingleton<T>(from: InjectionToken<T>, to: constructor<T>): DependencyContainer;
registerSingleton<T>(token: constructor<T>): DependencyContainer;
/**
* Register a type mapping (alias one token to another)
*/
registerType<T>(from: InjectionToken<T>, to: InjectionToken<T>): DependencyContainer;
/**
* Register a concrete instance directly
*/
registerInstance<T>(token: InjectionToken<T>, instance: T): DependencyContainer;Usage Examples:
// Value provider
container.register("config", { useValue: { apiUrl: "https://api.com" } });
// Factory provider
container.register("logger", {
useFactory: (c) => new Logger(c.resolve("config"))
});
// Class provider
container.register("UserService", UserService, { lifecycle: Lifecycle.Singleton });
// Constructor shorthand
container.register("UserService", UserService);
// Singleton registration
container.registerSingleton(DatabaseService);
container.registerSingleton("IUserRepo", UserRepository);
// Type mapping
container.registerType("ILogger", "ConsoleLogger");
// Instance registration
container.registerInstance("startTime", new Date());Resolve registered dependencies with single or multiple instance support.
/**
* Resolve a single instance of the registered dependency
* @param token - The injection token to resolve
* @returns Resolved instance of type T
*/
resolve<T>(token: InjectionToken<T>): T;
/**
* Resolve all registered instances for a token (useful for plugin patterns)
* @param token - The injection token to resolve all instances for
* @returns Array of all resolved instances
*/
resolveAll<T>(token: InjectionToken<T>): T[];Usage Examples:
// Single resolution
const userService = container.resolve<UserService>("UserService");
const logger = container.resolve(Logger);
// Multiple resolution (all registered instances)
const plugins = container.resolveAll<Plugin>("Plugin");
const validators = container.resolveAll<Validator>("Validator");Create child containers and manage container hierarchy for scoped dependency management.
/**
* Create a child container that inherits from this container
* Child containers can override parent registrations
* @returns New child DependencyContainer instance
*/
createChildContainer(): DependencyContainer;
/**
* Check if a token is registered in this container
* @param token - Token to check registration for
* @param recursive - Whether to check parent containers (default: true)
* @returns True if token is registered
*/
isRegistered<T>(token: InjectionToken<T>, recursive?: boolean): boolean;
/**
* Clear all registrations from this container
* Does not affect parent containers
*/
reset(): void;
/**
* Clear all cached instances but keep registrations
* Forces fresh instance creation on next resolve
*/
clearInstances(): void;Usage Examples:
// Child container usage
const childContainer = container.createChildContainer();
childContainer.register("ChildService", ChildService);
const hasService = childContainer.isRegistered("UserService"); // true (inherited)
const hasChild = container.isRegistered("ChildService"); // false (child-only)
// Container management
container.reset(); // Clear all registrations
container.clearInstances(); // Clear cached instances onlyRegister callbacks for pre and post resolution interception to customize dependency behavior.
/**
* Register a callback to execute before dependency resolution
* @param token - Token to intercept
* @param callback - Callback function to execute
* @param options - Interception options
*/
beforeResolution<T>(
token: InjectionToken<T>,
callback: PreResolutionInterceptorCallback<T>,
options?: InterceptorOptions
): void;
/**
* Register a callback to execute after dependency resolution
* @param token - Token to intercept
* @param callback - Callback function to execute
* @param options - Interception options
*/
afterResolution<T>(
token: InjectionToken<T>,
callback: PostResolutionInterceptorCallback<T>,
options?: InterceptorOptions
): void;Usage Examples:
// Logging interceptor
container.beforeResolution("UserService", (token, resolutionType) => {
console.log(`Resolving ${String(token)} as ${resolutionType}`);
});
container.afterResolution("UserService", (token, result, resolutionType) => {
console.log(`Resolved ${String(token)}: ${result}`);
});
// One-time interceptor
container.afterResolution(
"DatabaseService",
(token, result) => console.log("Database connected"),
{ frequency: "Once" }
);Dispose the container and all registered disposable resources.
/**
* Dispose the container and all registered disposable resources
* Calls dispose() on all instances that implement Disposable interface
* @returns Promise that resolves when all disposals complete
*/
dispose(): Promise<void>;Usage Examples:
// Proper cleanup
class DatabaseService implements Disposable {
async dispose() {
await this.connection.close();
}
}
container.registerSingleton(DatabaseService);
// Later, cleanup all resources
await container.dispose();// Main container interface
interface DependencyContainer extends Disposable {
register<T>(token: InjectionToken<T>, provider: Provider<T>, options?: RegistrationOptions): DependencyContainer;
registerSingleton<T>(from: InjectionToken<T>, to?: constructor<T>): DependencyContainer;
registerType<T>(from: InjectionToken<T>, to: InjectionToken<T>): DependencyContainer;
registerInstance<T>(token: InjectionToken<T>, instance: T): DependencyContainer;
resolve<T>(token: InjectionToken<T>): T;
resolveAll<T>(token: InjectionToken<T>): T[];
isRegistered<T>(token: InjectionToken<T>, recursive?: boolean): boolean;
reset(): void;
clearInstances(): void;
createChildContainer(): DependencyContainer;
beforeResolution<T>(token: InjectionToken<T>, callback: PreResolutionInterceptorCallback<T>, options?: InterceptorOptions): void;
afterResolution<T>(token: InjectionToken<T>, callback: PostResolutionInterceptorCallback<T>, options?: InterceptorOptions): void;
dispose(): Promise<void>;
}
// Interceptor options
interface InterceptorOptions {
frequency: Frequency;
}
// Callback types
type PreResolutionInterceptorCallback<T> = (token: InjectionToken<T>, resolutionType: ResolutionType) => void;
type PostResolutionInterceptorCallback<T> = (token: InjectionToken<T>, result: T | T[], resolutionType: ResolutionType) => void;Install with Tessl CLI
npx tessl i tessl/npm-tsyringe