inversify-inject-decorators
Lazy evaluated property injection decorators.
Motivation
Some frameworks and libraries take control over the creation of instances
of a given class. For example, React takes control over the creation of
instances of a given React component. This kind of frameworks and libraries
prevent us from being able to use constructor injection and as a result
they are not easy to integrate with InversifyJS.
InversifyJS also provides support for property injection but it also
requires the instances of a class to be created by InversifyJS.
The decorators included in this library will allow you to lazy-inject
properties even when the instances of a class cannot created by InversifyJS.
This library allows you to integrate InversifyJS with any library or
framework that takes control over the creation of instances of a
given class.
Installation
You can install inversify-inject-decorators
using npm:
$ npm install inversify inversify-inject-decorators reflect-metadata --save
The inversify-inject-decorators
type definitions are included in the npm module and require TypeScript 2.0.
Please refer to the InversifyJS documentation to learn more about the installation process.
Basic property lazy-injection with @lazyInject
The following example showcases how to inject into a property
using the @lazyInject
decorator:
import getDecorators from "inversify-inject-decorators";
import { Container, injectable, tagged, named } from "inversify";
let container = new Container();
let { lazyInject } = getDecorators(container);
let TYPES = { Weapon: "Weapon" };
interface Weapon {
name: string;
durability: number;
use(): void;
}
@injectable()
class Sword implements Weapon {
public name: string;
public durability: number;
public constructor() {
this.durability = 100;
this.name = "Sword";
}
public use() {
this.durability = this.durability - 10;
}
}
class Warrior {
@lazyInject(TYPES.Weapon)
public weapon: Weapon;
}
container.bind<Weapon>(TYPES.Weapon).to(Sword);
let warrior = new Warrior();
console.log(warrior.weapon instanceof Sword);
Named property injection with @lazyInjectNamed
The following example showcases how to inject into a named property
using the @lazyInjectNamed
decorator:
import getDecorators from "inversify-inject-decorators";
import { Container, injectable, named } from "inversify";
let container = new Container();
let { lazyInjectNamed } = getDecorators(container);
let TYPES = { Weapon: "Weapon" };
interface Weapon {
name: string;
durability: number;
use(): void;
}
@injectable()
class Sword implements Weapon {
public name: string;
public durability: number;
public constructor() {
this.durability = 100;
this.name = "Sword";
}
public use() {
this.durability = this.durability - 10;
}
}
@injectable()
class Shuriken implements Weapon {
public name: string;
public durability: number;
public constructor() {
this.durability = 100;
this.name = "Shuriken";
}
public use() {
this.durability = this.durability - 10;
}
}
class Warrior {
@lazyInjectNamed(TYPES.Weapon, "not-throwwable")
@named("not-throwwable")
public primaryWeapon: Weapon;
@lazyInjectNamed(TYPES.Weapon, "throwwable")
@named("throwwable")
public secondaryWeapon: Weapon;
}
container.bind<Weapon>(TYPES.Weapon).to(Sword).whenTargetNamed("not-throwwable");
container.bind<Weapon>(TYPES.Weapon).to(Shuriken).whenTargetNamed("throwwable");
let warrior = new Warrior();
console.log(warrior.primaryWeapon instanceof Sword);
console.log(warrior.primaryWeapon instanceof Shuriken);
Tagged property injection with @lazyInjectTagged
The following example showcases how to inject a tagged property
using the @lazyInjectTagged
decorator:
import getDecorators from "inversify-inject-decorators";
import { Container, injectable, tagged } from "inversify";
let container = new Container();
let { lazyInjectTagged } = getDecorators(container);
let TYPES = { Weapon: "Weapon" };
interface Weapon {
name: string;
durability: number;
use(): void;
}
@injectable()
class Sword implements Weapon {
public name: string;
public durability: number;
public constructor() {
this.durability = 100;
this.name = "Sword";
}
public use() {
this.durability = this.durability - 10;
}
}
@injectable()
class Shuriken implements Weapon {
public name: string;
public durability: number;
public constructor() {
this.durability = 100;
this.name = "Shuriken";
}
public use() {
this.durability = this.durability - 10;
}
}
class Warrior {
@lazyInjectTagged(TYPES.Weapon, "throwwable", false)
@tagged("throwwable", false)
public primaryWeapon: Weapon;
@lazyInjectTagged(TYPES.Weapon, "throwwable", true)
@tagged("throwwable", true)
public secondaryWeapon: Weapon;
}
container.bind<Weapon>(TYPES.Weapon).to(Sword).whenTargetTagged("throwwable", false);
container.bind<Weapon>(TYPES.Weapon).to(Shuriken).whenTargetTagged("throwwable", true);
let warrior = new Warrior();
console.log(warrior.primaryWeapon instanceof Sword);
console.log(warrior.primaryWeapon instanceof Shuriken);
Multi-injection into a property with @lazyMultiInject
The following example showcases how to multi-inject a property
using the @lazyMultiInject
decorator:
import getDecorators from "inversify-inject-decorators";
import { Container, injectable } from "inversify";
let container = new Container();
let { lazyMultiInject } = getDecorators(container);
let TYPES = { Weapon: "Weapon" };
interface Weapon {
name: string;
durability: number;
use(): void;
}
@injectable()
class Sword implements Weapon {
public name: string;
public durability: number;
public constructor() {
this.durability = 100;
this.name = "Sword";
}
public use() {
this.durability = this.durability - 10;
}
}
@injectable()
class Shuriken implements Weapon {
public name: string;
public durability: number;
public constructor() {
this.durability = 100;
this.name = "Shuriken";
}
public use() {
this.durability = this.durability - 10;
}
}
class Warrior {
@lazyMultiInject(TYPES.Weapon)
public weapons: Weapon[];
}
container.bind<Weapon>(TYPES.Weapon).to(Sword);
container.bind<Weapon>(TYPES.Weapon).to(Shuriken);
let warrior = new Warrior();
console.log(warrior.weapons[0] instanceof Sword);
console.log(warrior.weapons[1] instanceof Shuriken);