This project is a barebones IoC container written in TypeScript: No decorators. No metadata reflection. Unlike many lightweight IoC approaches, this container allows registering virtually any value while keeping service registration flexible and explicit.
class Test{};
class Test2 { constructor(private x: Test) {} }
const container = Container.create()
.bind(symbols.array, [1, 2, 3, 4])
.bind(symbols.instantiable, Test)
.bind(symbols.instance, new Test())
.bind(symbols.factory, () => 1)
.bind(Test)
.bind(Test2, (container) => new Test2(container.get(Test)))
.bind(symbols.string, 'Hello!')
.bind(symbols.number, 13);
const arr = container.get(symbols.array);
const test = container.get(Test2);The implementation avoids reflection-based analysis of constructor parameters. Instead of relying on reflection or decorators, dependencies are intended to be wired explicitly through creator functions. This keeps object construction transparent, type-safe, and still easy to refactor.
export class OrderQueryHandler {
constructor(private repo: order.Repository) {}
public static construct(container: Container): OrderQueryHandler {
return new OrderQueryHandler(container.get(order.symbols.repository));
} container.bind(OrderQueryHandler, OrderQueryHandler.construct);
const handler = container.get(OrderQueryHandler);With this approach, constructor changes remain easy to manage because the creator function lives right next to the constructor.
The current implementation intentionally focuses on explicit and lightweight dependency wiring.
Potential future extensions include:
- Scoped and transient lifetimes
- Circular dependency detection
- Async factory support
- Improved diagnostics and error messages
Licensed under the Apache 2.0 License.