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.