注入一个工厂
绑定一个抽象到用户自定义的工厂。
@injectable()
class Ninja implements Ninja {
private _katana: Katana;
private _shuriken: Shuriken;
public constructor(
@inject("Factory<Katana>") katanaFactory: () => Katana,
@inject("Shuriken") shuriken: Shuriken
) {
this._katana = katanaFactory();
this._shuriken = shuriken;
}
public fight() {
return this._katana.hit();
}
public sneak() {
return this._shuriken.throw();
}
}
container
.bind<interfaces.Factory<Katana>>("Factory<Katana>")
.toFactory<Katana>((context: interfaces.Context) => {
return () => {
return context.container.get<Katana>("Katana");
};
});
你也可以定义带参数的工厂:
container
.bind<interfaces.Factory<Weapon>>("Factory<Weapon>")
.toFactory<Weapon>((context: interfaces.Context) => {
return (throwable: boolean) => {
if (throwable) {
return context.container.getTagged<Weapon>("Weapon", "throwable", true);
} else {
return context.container.getTagged<Weapon>(
"Weapon",
"throwable",
false
);
}
};
});
有时候在不同的运行时你也许需要传递参数给到某工厂:
container.bind<Engine>("Engine").to(PetrolEngine).whenTargetNamed("petrol");
container.bind<Engine>("Engine").to(DieselEngine).whenTargetNamed("diesel");
container
.bind<interfaces.Factory<Engine>>("Factory<Engine>")
.toFactory<Engine>((context) => {
return (named: string) => (displacement: number) => {
let engine = context.container.getNamed<Engine>("Engine", named);
engine.displacement = displacement;
return engine;
};
});
@injectable()
class DieselCarFactory implements CarFactory {
private _dieselFactory: (displacement: number) => Engine;
constructor(
@inject("Factory<Engine>")
factory: (category: string) => (displacement: number) => Engine // 注入一个引擎工厂
) {
this._dieselFactory = factory("diesel"); // 创建一个 diesel 引擎工厂
}
public createEngine(displacement: number): Engine {
return this._dieselFactory(displacement); // 创建一个具体的 diesel 引擎
}
}