Skip to content

snatalenko/di0

Repository files navigation

di0 — Dependency Injection for TS/ES6+

Version Downloads Coverage License tests/audit

Zero-config DI container. Register classes or factories by alias; dependencies are injected automatically via constructor destructuring.

Install

npm install di0

Quick Start

const { ContainerBuilder } = require('di0');

class Engine {}

class Car {
  constructor({ engine }) {
    this.engine = engine;
  }
}

const builder = new ContainerBuilder();
builder.register(Engine).as('engine');
builder.register(Car).as('car');

const container = builder.container();
container.car.engine instanceof Engine; // true

Factories

Register a factory function instead of a class:

builder.register(({ engine }) => new Car(engine), 'car');

Instance Lifetimes

Method Behavior
.asInstancePerContainer() Default. One instance per container.
.asSingleInstance() One instance shared across parent and all derived containers.
.asInstancePerDependency() New instance on every access.
builder.register(Engine).as('engine').asSingleInstance();

Container API

container.engine;                          // get by alias (lazy)
container.get('engine');                   // same as above
container.getAll('plugin');                // all registrations under alias
container.has('engine');                   // check without instantiating
container.createInstance(Car, { extra });  // instantiate with extra deps

Collections (asOneOf)

Register multiple types under the same alias to expose them as an array:

builder.register(GasEngine).asOneOf('engines');
builder.register(ElectricEngine).asOneOf('engines');

const container = builder.container();
container.engines; // [GasEngine instance, ElectricEngine instance]

Works with all instance lifetimes and container inheritance — child containers include parent registrations.

Auto-wiring (addResolver)

Register a predicate to automatically wire unaliased types to an alias. The predicate receives an instance; exactly one type must match — multiple matches throw.

builder.addResolver(i => i instanceof Engine, 'engine');
builder.addResolver(i => 'wheels' in i, 'car');

builder.register(Engine);
builder.register(Car); // Car: constructor({ engine }) { ... }

const { car, engine } = builder.container();

Registration order does not matter. Singleton resolver-matched instances propagate to derived containers.

Container Inheritance

Derive a child container that shares singletons with its parent:

const child = container.builder()
  .register(Plugin).as('plugin')
  .container();

// child has all parent services + Plugin
// singletons from parent are reused

Initializers (Side Effects)

Register without an alias to run code eagerly when the container is created:

builder.register(({ db }) => db.connect());  // no .as() — runs on container()

Logging

Register a logger alias to trace instantiation:

builder.register(() => console, 'logger');
// logs: "engine instance created", "car.engine instance created", …

The logger must implement { log(level, message) }.

About

Dependency injection for ES6 classes

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors