绑定语法
绑定语法作为流畅的接口提供,源于使用 容器 API 或 容器模块 API。
BindingToSyntax
interface BindingToSyntax<T> {
// ...
}
表示给定服务标识符的服务绑定。
const bindingToSyntax = container.bind('service-id');
进一步的文档将此服务标识符称为“给定服务标识符”。
to
to(constructor: interfaces.Newable<T>): interfaces.BindingInWhenOnSyntax<T>;
将类实例化绑定到给定的服务绑定。每当解析服务时,都会调用类构造函数来构建解析值。
const container: Container = new Container();
container.bind<Weapon>('Weapon').to(Katana);
const katana: Weapon = container.get<Weapon>('Weapon');
toSelf
toSelf(): interfaces.BindingInWhenOnSyntax<T>;
如果给定的服务标识符是一个类,则建立到该类的类型绑定。
const container: Container = new Container();
container.bind<Weapon>(Katana).toSelf();
const katana: Weapon = container.get<Weapon>(Katana);
toConstantValue
toConstantValue(value: T): interfaces.BindingWhenOnSyntax<T>;
将单例作用域中的值绑定到给定的服务标识符。
const container: Container = new Container();
container.bind<Weapon>('Weapon').toConstantValue(new Katana());
const katana: Weapon = container.get<Weapon>('Weapon');
toDynamicValue
toDynamicValue(func: interfaces.DynamicValue<T>): interfaces.BindingInWhenOnSyntax<T>;
将函数绑定到给定的服务 ID。每当解析服务时,都会调用传递的函数来构建解析值。
请记住,如果服务在当前作用域中已缓存,则不会解析该服务。
const container: Container = new Container();
container.bind<Weapon>('Weapon').toDynamicValue((): Weapon => new Katana());
const katana: Weapon = container.get<Weapon>('Weapon');
toConstructor
toConstructor<T2>(constructor: interfaces.Newable<T2>): interfaces.BindingWhenOnSyntax<T>;
将类绑定到给定的服务 ID。每当解析服务时,类构造函数将作为解析值传递。
const container: Container = new Container();
container.bind<Weapon>('WeaponConstructor').toConstructor(Katana);
const katanaConstructor: interfaces.Newable<Weapon> =
container.get<interfaces.Newable<Weapon>>('WeaponConstructor');
toFactory
toFactory<T2>(factory: interfaces.FactoryCreator<T2>): interfaces.BindingWhenOnSyntax<T>;
将工厂绑定到给定的服务标识符。每当解析服务时,工厂将作为解析值传递。
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, [string], [number]>((context: interfaces.Context) => {
return (named: string) => (displacement: number) => {
const engine: Engine = context.container.getNamed<Engine>(
'Engine',
named,
);
engine.displacement = displacement;
return engine;
};
});
@injectable()
class DieselCarFactory implements CarFactory {
readonly #dieselFactory: (displacement: number) => Engine;
constructor(
@inject('Factory<Engine>')
factory: (category: string) => (displacement: number) => Engine, // Injecting an engine factory
) {
// Creating a diesel engine factory
this.#dieselFactory = factory('diesel');
}
public createEngine(displacement: number): Engine {
// Creating a concrete diesel engine
return this.#dieselFactory(displacement);
}
}
toFunction
toFunction(func: T): interfaces.BindingWhenOnSyntax<T>;
BindingToSyntax.toConstantValue 的别名,仅限于函数。
toAutoFactory
toAutoFactory<T2>(serviceIdentifier: interfaces.ServiceIdentifier<T2>): interfaces.BindingWhenOnSyntax<T>;
将与目标服务标识符关联的服务工厂绑定到给定的服务标识符。
@injectable()
class Ninja implements Ninja {
readonly #katana: Katana;
readonly #shuriken: Shuriken;
constructor(
@inject('Factory<Katana>') katanaFactory: interfaces.AutoFactory<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('Katana').to(Katana);
container.bind('Shuriken').to(Shuriken);
container
.bind<interfaces.Factory<Katana>>('Factory<Katana>')
.toAutoFactory<Katana>('Katana');
container.bind(Ninja).toSelf();
toAutoNamedFactory
toAutoNamedFactory<T2>(serviceIdentifier: interfaces.ServiceIdentifier<T2>): BindingWhenOnSyntax<T>;
将与目标服务标识符和名称关联的服务工厂绑定到给定的服务标识符。
@injectable()
class Ninja implements Ninja {
readonly #katana: Katana;
readonly #shuriken: Shuriken;
constructor(
@inject('Factory<Weapon>')
katanaFactory: interfaces.AutoNamedFactory<Weapon>,
) {
this.#katana = katanaFactory('katana') as Katana;
this.#shuriken = katanaFactory('shuriken') as Shuriken;
}
public fight() {
return this.#katana.hit();
}
public sneak() {
return this.#shuriken.throw();
}
}
container.bind<Weapon>('Weapon').to(Katana).whenTargetNamed('katana');
container.bind<Weapon>('Weapon').to(Shuriken).whenTargetNamed('shuriken');
container
.bind<interfaces.AutoNamedFactory<Weapon>>('Factory<Weapon>')
.toAutoNamedFactory<Weapon>('Weapon');
container.bind(Ninja).toSelf();
toProvider
toProvider<T2>(provider: interfaces.ProviderCreator<T2>): interfaces.BindingWhenOnSyntax<T>;
将与目标服务标识符关联的服务提供者绑定到给定的服务标识符。提供者只是一个异步工厂。
const container: Container = new Container();
interface Sword {
material: string;
damage: number;
}
@injectable()
class Katana implements Sword {
public material!: string;
public damage!: number;
}
type SwordProvider = (material: string, damage: number) => Promise<Sword>;
container.bind<Sword>('Sword').to(Katana);
container
.bind<SwordProvider>('SwordProvider')
.toProvider<Sword>((context: interfaces.Context) => {
return async (material: string, damage: number): Promise<Sword> => {
// Custom args!
return new Promise<Sword>(
(resolve: (value: Sword | PromiseLike<Sword>) => void) => {
setTimeout(() => {
const katana: Sword = context.container.get<Sword>('Sword');
katana.material = material;
katana.damage = damage;
resolve(katana);
}, 10);
},
);
};
});
const katanaProvider: SwordProvider =
container.get<SwordProvider>('SwordProvider');
const powerfulGoldKatana: Promise<Sword> = katanaProvider('gold', 100);
const notSoPowerfulGoldKatana: Promise<Sword> = katanaProvider('gold', 10);
toService
toService(service: interfaces.ServiceIdentifier<T>): void;
将绑定到目标服务标识符的服务绑定到给定的服务标识符。
const container: Container = new Container();
container.bind(lorcanaCardCatalogProviderSymbol).to(LorcanaCardCatalogProvider);
container.bind(mtgCardCatalogProviderSymbol).to(MtgCardCatalogProvider);
container
.bind(cardCatalogProviderSymbol)
.toService(lorcanaCardCatalogProviderSymbol);
container
.bind(cardCatalogProviderSymbol)
.toService(mtgCardCatalogProviderSymbol);
const cardCatalogProviders: CardCatalogProvider<unknown>[] = container.getAll(
cardCatalogProviderSymbol,
);
BindingInSyntax
interface BindingInSyntax<T> {
// ...
}
表示给定服务标识符和服务解析(如构造函数、工厂或提供者)的服务绑定。
inSingletonScope
inSingletonScope(): BindingWhenOnSyntax<T>;
将绑定作用域设置为单例。有关更多信息,请参阅 文档。
inTransientScope
inTransientScope(): BindingWhenOnSyntax<T>;
将绑定作用域设置为瞬态。有关更多信息,请参阅 文档。
inRequestScope
inRequestScope(): BindingWhenOnSyntax<T>;
将绑定作用域设置为请求。有关更多信息,请参阅 文档。
BindingOnSyntax
interface BindingOnSyntax<T> {
// ...
}
允许设置绑定激活和停用处理程序。
onActivation
onActivation(fn: (context: Context, injectable: T) => T | Promise<T>): BindingWhenSyntax<T>;
设置绑定激活处理程序。激活处理程序在依赖项解析之后且添加到作用域缓存之前调用。如果依赖项取自作用域缓存,则不会调用激活处理程序。
@injectable()
class Katana {
public use(): string {
return 'hit!';
}
}
container
.bind<Katana>('Katana')
.to(Katana)
.onActivation((_context: interfaces.Context, katana: Katana) => {
const handler: ProxyHandler<() => string> = {
apply: function (
target: () => string,
thisArgument: unknown,
argumentsList: [],
) {
console.log(`Starting: ${new Date().getTime().toString()}`);
const result: string = target.apply(thisArgument, argumentsList);
console.log(`Finished: ${new Date().getTime().toString()}`);
return result;
},
};
katana.use = new Proxy(katana.use.bind(katana), handler);
return katana;
});
onDeactivation
onDeactivation(fn: (injectable: T) => void | Promise<void>): BindingWhenSyntax<T>;
在单例作用域绑定上设置绑定停用处理程序。当绑定从容器中解绑时,将调用停用处理程序。
只有单例作用域绑定可以具有停用处理程序。如果您尝试向非单例绑定添加停用处理程序,则会抛出错误。
BindingWhenSyntax
interface BindingWhenSyntax<T> {
// ...
}
允许设置绑定约束。
when
为当前绑定设置约束。
when(constraint: (request: Request) => boolean): BindingOnSyntax<T>;
const ninjaId: symbol = Symbol.for('Ninja');
const weaponId: symbol = Symbol.for('Weapon');
@injectable()
class Ninja {
constructor(
@inject(weaponId)
@named('shuriken')
public readonly weapon: Weapon,
) {}
}
container.bind<Ninja>(ninjaId).to(Ninja);
const whenTargetNamedConstraint: (
name: string,
) => (request: interfaces.Request) => boolean =
(name: string) =>
(request: interfaces.Request): boolean =>
request.target.matchesNamedTag(name);
container
.bind<Weapon>(weaponId)
.to(Katana)
.when(whenTargetNamedConstraint('katana'));
container
.bind<Weapon>(weaponId)
.to(Shuriken)
.when(whenTargetNamedConstraint('shuriken'));
const ninja: Ninja = container.get(ninjaId);
// Returns 5
const ninjaDamage: number = ninja.weapon.damage;
在前面的示例中,实现了一个自定义约束,仅当目标名称为特定名称时才使用绑定。
whenTargetNamed
约束绑定仅当目标名称为特定名称时才使用。
whenTargetNamed(name: string | number | symbol): BindingOnSyntax<T>;
whenTargetIsDefault
whenTargetIsDefault(): BindingOnSyntax<T>;
约束绑定仅当目标没有名称也没有标签时才使用。
whenTargetTagged
whenTargetTagged(tag: string | number | symbol, value: unknown): BindingOnSyntax<T>;
约束绑定仅当目标标签为特定标签时才使用。
whenInjectedInto
whenInjectedInto(parent: NewableFunction | string): BindingOnSyntax<T>;
约束绑定仅当父目标服务标识符为特定标识符时才使用。
whenParentNamed
whenParentNamed(name: string | number | symbol): BindingOnSyntax<T>;
约束绑定仅当父目标名称为特定名称时才使用。
whenParentTagged
whenParentTagged(tag: string | number | symbol, value: unknown): BindingOnSyntax<T>;
约束绑定仅当父目标标签为特定标签时才使用。
whenAnyAncestorIs
whenAnyAncestorIs(ancestor: NewableFunction | string): BindingOnSyntax<T>;
约束绑定仅当任何祖先目标服务标识符为特定标识符时才使用。
whenNoAncestorIs
whenNoAncestorIs(ancestor: NewableFunction | string): BindingOnSyntax<T>;
约束绑定仅当没有祖先目标服务标识符为特定标识符时才使用。
whenAnyAncestorNamed
whenAnyAncestorNamed(name: string | number | symbol): BindingOnSyntax<T>;
约束绑定仅当任何祖先目标名称为特定名称时才使用。
whenAnyAncestorTagged
whenAnyAncestorTagged(tag: string | number | symbol, value: unknown): BindingOnSyntax<T>;
约束绑定仅当任何祖先目标标签为特定标签时才使用。
whenNoAncestorNamed
whenNoAncestorNamed(name: string | number | symbol): BindingOnSyntax<T>;
约束绑定仅当没有祖先目标名称为特定名称时才使用。
whenNoAncestorTagged
whenNoAncestorTagged(tag: string | number | symbol, value: unknown): BindingOnSyntax<T>;
约束绑定仅当没有祖先目标标签为特定标签时才使用。
whenAnyAncestorMatches
whenAnyAncestorMatches(constraint: (request: Request) => boolean): BindingOnSyntax<T>;
约束绑定仅当任何祖先匹配特定约束时才使用。
whenNoAncestorMatches
whenNoAncestorMatches(constraint: (request: Request) => boolean): BindingOnSyntax<T>;
约束绑定仅当没有祖先匹配特定约束时才使用。
BindingWhenOnSyntax
BindingWhenSyntax 和 BindingOnSyntax 的联合。
export interface BindingWhenOnSyntax<T>
extends BindingWhenSyntax<T>,
BindingOnSyntax<T> {}
BindingInWhenOnSyntax
BindingInSyntax 和 BindingWhenOnSyntax 的联合。
export interface BindingInWhenOnSyntax<T>
extends BindingInSyntax<T>,
BindingWhenOnSyntax<T> {}