InversifyJS IoC Container

8.1.0 · active · verified Sun Apr 19

InversifyJS is a robust and lightweight Inversion of Control (IoC) container for JavaScript and TypeScript applications, currently at version 8.1.0. It facilitates Dependency Injection (DI) by using decorators and TypeScript's reflection capabilities to manage the instantiation and injection of dependencies, promoting adherence to SOLID principles, good OOP, and IoC practices. The library is actively maintained with frequent minor and patch releases across its core and ecosystem packages, addressing new features and bug fixes. Key differentiators include its strong TypeScript integration, minimal runtime overhead, and a developer-friendly API designed to enhance modularity, testability, and maintainability. InversifyJS emphasizes a explicit dependency graph, helping developers build scalable applications by reducing coupling between components. It relies heavily on `reflect-metadata` for design-time type information, which is a fundamental aspect of its operation.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates the core concepts of InversifyJS: defining interfaces, using symbols for binding identifiers, marking classes with `@injectable`, injecting dependencies with `@inject`, configuring the `Container` with `bind().to()`, and finally resolving an instance using `container.get()`. It highlights the necessary `reflect-metadata` import.

import 'reflect-metadata';
import { Container, injectable, inject } from 'inversify';

// 1. Define interfaces (abstractions)
interface Warrior {
  fight(): string;
  sneak(): string;
}

interface Weapon {
  hit(): string;
}

interface ThrowableWeapon {
  throw(): string;
}

// 2. Define binding identifiers (symbols or classes)
const TYPES = {
  Warrior: Symbol.for('Warrior'),
  Weapon: Symbol.for('Weapon'),
  ThrowableWeapon: Symbol.for('ThrowableWeapon'),
};

// 3. Implement concrete classes and use decorators
@injectable()
class Katana implements Weapon {
  public hit(): string {
    return 'cut!';
  }
}

@injectable()
class Shuriken implements ThrowableWeapon {
  public throw(): string {
    return 'hit!';
  }
}

@injectable()
class Ninja implements Warrior {
  private _katana: Weapon;
  private _shuriken: ThrowableWeapon;

  public constructor(
    @inject(TYPES.Weapon) katana: Weapon,
    @inject(TYPES.ThrowableWeapon) shuriken: ThrowableWeapon,
  ) {
    this._katana = katana;
    this._shuriken = shuriken;
  }

  public fight(): string {
    return this._katana.hit();
  }

  public sneak(): string {
    return this._shuriken.throw();
  }
}

// 4. Create and configure a container
const myContainer = new Container();
myContainer.bind<Warrior>(TYPES.Warrior).to(Ninja);
myContainer.bind<Weapon>(TYPES.Weapon).to(Katana);
myContainer.bind<ThrowableWeapon>(TYPES.ThrowableWeapon).to(Shuriken);

// 5. Resolve dependencies
const ninja = myContainer.get<Warrior>(TYPES.Warrior);

console.log(ninja.fight()); // Expected output: cut!
console.log(ninja.sneak()); // Expected output: hit!

view raw JSON →