Skip to main content
Version: Next

Binding

A binding represents the relationship between a service identifier and its resolution. Bindings are added to a container to configure it to provide services.

const container: Container = new Container();
container.bind<Weapon>('Weapon').to(Katana).inSingletonScope();

When the binding is added to the container, the container is configured to provide a resolved value for the service identifier Weapon by resolving the Katana class. container.bind creates a new binding with certain properties, which are explained below.

Relying on emitted class metadata

When using TypeScript, you can rely on the emitted class metadata to avoid having to manually specify the service identifier. This is done by using the @injectable decorator from inversify on the class you want to bind. You need to enable the emitDecoratorMetadata TypeScript compiler option.

export class Katana {
public readonly damage: number = 10;
}

@injectable()
export class Samurai {
public readonly katana: Katana;

constructor(katana: Katana) {
this.katana = katana;
}
}

const container: Container = new Container();

container.bind(Katana).toSelf().inSingletonScope();
container.bind(Samurai).toSelf().inSingletonScope();

const samurai: Samurai = container.get(Samurai);

Autobinding

InversifyJS provides a feature called autobinding that allows you to automatically bind classes. Whenever a class service is being resolved and no bindings are found in the planning phase, the container adds a type binding to the requested class before proceeding with the planning phase. This feature is disabled by default. To enable it, you need to pass the autoBind option to the container or pass an autobind option when calling container.get.

export class Katana {
public readonly damage: number = 10;
}

@injectable()
export class Samurai {
public readonly katana: Katana;

constructor(katana: Katana) {
this.katana = katana;
}
}

const container: Container = new Container();

const samurai: Samurai = container.get(Samurai, { autobind: true });

Binding properties

A binding has the following properties:

Service identifier

The identifier of the service for which a resolution is provided.

Scope

The scope determines the caching strategy used to decide whether the service should be resolved or a cached value should be provided.

Request

When the service is resolved within the same container.get request, the same resolved value will be used.

export class LegendaryWarrior {
constructor(
@inject('Weapon') public readonly firstWeapon: Weapon,
@inject('Weapon') public readonly secondWeapon: Weapon,
@inject('Weapon') public readonly thirdWeapon: Weapon,
) {}
}

const container: Container = new Container();
container.bind<Weapon>('Weapon').to(Katana).inRequestScope();
container.bind(LegendaryWarrior).toSelf();

const firstKatana: Weapon = container.get<Weapon>('Weapon');
const secondKatana: Weapon = container.get<Weapon>('Weapon');

const legendaryWarrior: LegendaryWarrior = container.get(LegendaryWarrior);

// Returns false
const isSameKatana: boolean = firstKatana === secondKatana;

// Returns true
const warriorHasSameKatana: boolean =
legendaryWarrior.firstWeapon === legendaryWarrior.secondWeapon &&
legendaryWarrior.secondWeapon === legendaryWarrior.thirdWeapon;

Singleton

When the service is resolved, the same cached resolved value will be used.

const container: Container = new Container();
container.bind<Weapon>('Weapon').to(Katana).inSingletonScope();

const firstKatana: Weapon = container.get<Weapon>('Weapon');
const secondKatana: Weapon = container.get<Weapon>('Weapon');

// Returns true
const isSameKatana: boolean = firstKatana === secondKatana;

Transient

When the service is resolved, a new resolved value will be used each time.

const container: Container = new Container();
container.bind<Weapon>('Weapon').to(Katana).inTransientScope();

const firstKatana: Weapon = container.get<Weapon>('Weapon');
const secondKatana: Weapon = container.get<Weapon>('Weapon');

// Returns false
const isSameKatana: boolean = firstKatana === secondKatana;

Constraint

Specifies whether the binding is used to provide a resolved value for the given service identifier. Refer to the API docs for more information.

Lifecycle handlers

Handlers that are called after a resolved value is provided or a singleton-scoped binding is deactivated. Refer to the API docs for more information.