容器
InversifyJS 容器是首先通过绑定配置依赖项,然后可能重新配置和删除依赖项的地方。在这方面,可以直接在容器上工作,也可以利用容器模块。
你可以使用 get 方法查询配置并解析配置的依赖项。
你可以使用容器激活处理程序对解析做出反应,并使用容器停用处理程序对解绑做出反应。
你可以创建容器层级结构,其中容器祖先可以为后代提供依赖项。
为了进行测试,可以将状态作为快照保存在堆栈上,并在以后恢复。
容器选项
可以将容器选项传递给 Container 构造函数,如果你不提供或提供但省略了选项,则将提供默认值。 选项可以在构造后更改,如果你不为从 Container 创建的子容器提供选项,则这些选项将由子容器共享。
autobind
autobind?: true;
自动将未绑定的类服务绑定到自身的选项。每当解析实例时,如果未找到请求服务的绑定,容器将尝试添加绑定。
parent
parent?: Container | undefined;
父容器(如果有)。有关更多信息,请参阅 容器层级结构文档。
defaultScope
defaultScope?: BindingScope | undefined;
绑定的默认作用域。
bind
bind<T>(serviceIdentifier: ServiceIdentifier<T>): BindToFluentSyntax<T>
设置一个新的绑定。
除非另有说明,否则绑定作用域默认为 瞬态。
get
get<T>(serviceIdentifier: ServiceIdentifier<T>, options: OptionalGetOptions): T | undefined;
get<T>(serviceIdentifier: ServiceIdentifier<T>, options?: GetOptions): T;
通过其运行时标识符解析依赖项。运行时标识符必须仅与一个绑定关联,并且绑定必须同步解析,否则将抛出错误。
const container: Container = new Container();
container.bind<Weapon>('Weapon').to(Katana);
const katana: Weapon = container.get<Weapon>('Weapon');
getAsync
getAsync<T>(serviceIdentifier: ServiceIdentifier<T>, options: OptionalGetOptions): Promise<T | undefined>;
getAsync<T>(serviceIdentifier: ServiceIdentifier<T>, options?: GetOptions): Promise<T>;
通过其运行时标识符解析依赖项。运行时标识符必须仅与一个绑定关联,否则将抛出错误。
async function buildLevel1(): Promise<Level1> {
return new Level1();
}
const container: Container = new Container();
container
.bind('Level1')
.toDynamicValue(async (): Promise<Level1> => buildLevel1());
const level1: Promise<Level1> = container.getAsync<Level1>('Level1');
getAll
getAll<T>(serviceIdentifier: ServiceIdentifier<T>, options?: GetAllOptions): T[];
获取给定标识符的所有可用绑定。所有绑定必须同步解析,否则将抛出错误:
const container: Container = new Container();
container.bind<Weapon>('Weapon').to(Katana);
container.bind<Weapon>('Weapon').to(Shuriken);
// returns Weapon[] with both Katana and Shuriken instances
const weapons: Weapon[] = container.getAll<Weapon>('Weapon');
getAllAsync
getAllAsync<T>(serviceIdentifier: ServiceIdentifier<T>, options?: GetAllOptions): Promise<T[]>
获取给定标识符的所有可用绑定:
const container: Container = new Container();
container.bind<Weapon>('Weapon').toDynamicValue(async () => new Katana());
container.bind<Weapon>('Weapon').to(Shuriken);
const weapons: Promise<Weapon[]> = container.getAllAsync<Weapon>('Weapon');
isBound
isBound(serviceIdentifier: ServiceIdentifier<unknown>, options?: IsBoundOptions): boolean;
你可以使用 isBound 方法检查给定服务标识符是否有已注册的绑定。
interface Warrior {
kind: string;
}
const katanaSymbol: symbol = Symbol.for('Katana');
const warriorSymbol: symbol = Symbol.for('Warrior');
@injectable()
class Ninja implements Warrior {
public readonly kind: string = 'ninja';
}
@injectable()
class Katana {}
const container: Container = new Container();
container.bind<Warrior>(Ninja).to(Ninja);
container.bind<Warrior>(warriorSymbol).to(Ninja);
// returns true
const isNinjaBound: boolean = container.isBound(Ninja);
// returns true
const isWarriorSymbolBound: boolean = container.isBound(warriorSymbol);
// returns false
const isKatanaBound: boolean = container.isBound(Katana);
// returns false
const isKatanaSymbolBound: boolean = container.isBound(katanaSymbol);
isCurrentBound
isCurrentBound(serviceIdentifier: ServiceIdentifier<unknown>, options?: IsBoundOptions): boolean;
你可以使用 isCurrentBound 方法检查给定服务标识符是否仅在当前容器中有已注册的绑定。
interface Warrior {
kind: string;
}
const katanaSymbol: symbol = Symbol.for('Katana');
const warriorSymbol: symbol = Symbol.for('Warrior');
@injectable()
class Ninja implements Warrior {
public readonly kind: string = 'ninja';
}
@injectable()
class Katana {}
const container: Container = new Container();
container.bind<Warrior>(Ninja).to(Ninja);
container.bind<Warrior>(warriorSymbol).to(Ninja);
const containerChild: Container = new Container({ parent: container });
containerChild.bind<Katana>(Katana).to(Katana);
containerChild.bind<Katana>(katanaSymbol).to(Katana);
// returns false
const isNinjaBound: boolean = containerChild.isCurrentBound(Ninja);
// returns false
const isWarriorSymbolBound: boolean =
containerChild.isCurrentBound(warriorSymbol);
// returns true
const isKatanaBound: boolean = containerChild.isCurrentBound(Katana);
// returns true
const isKatanaSymbolBound: boolean =
containerChild.isCurrentBound(katanaSymbol);
load
load(...modules: ContainerModule[]): Promise<void>;
调用每个模块的注册方法。请参阅 ContainerModule API 文档。
loadSync
loadSync(...modules: ContainerModule[]): void;
load 的同步版本。调用每个模块的注册方法。如果任何模块加载是异步的,将抛出错误。请参阅 ContainerModule API 文档。
onActivation
onActivation<T>(serviceIdentifier: ServiceIdentifier<T>, onActivation: BindingActivation<T>): void;
为与服务标识符关联的所有服务添加激活处理程序。
interface Weapon {
damage: number;
}
export class Katana implements Weapon {
#damage: number = 10;
public get damage(): number {
return this.#damage;
}
public improve(): void {
this.#damage += 2;
}
}
const container: Container = new Container();
container.bind<Weapon>('Weapon').to(Katana);
container.onActivation(
'Weapon',
(_context: ResolutionContext, katana: Katana): Katana | Promise<Katana> => {
katana.improve();
return katana;
},
);
// Katana.damage is 12
const katana: Weapon = container.get<Weapon>('Weapon');
onDeactivation
onDeactivation<T>(serviceIdentifier: ServiceIdentifier<T>, onDeactivation: BindingDeactivation<T>): void;
为服务标识符添加停用处理程序。
interface Weapon {
damage: number;
}
class Katana implements Weapon {
readonly #damage: number = 10;
public get damage(): number {
return this.#damage;
}
}
const container: Container = new Container();
container.bind<Weapon>('Weapon').to(Katana).inSingletonScope();
container.get('Weapon');
container.onDeactivation('Weapon', (weapon: Weapon): void | Promise<void> => {
console.log(`Deactivating weapon with damage ${weapon.damage.toString()}`);
});
await container.unbind('Weapon');
rebind
async rebind<T>(serviceIdentifier: ServiceIdentifier<T>): Promise<BindToFluentSyntax<T>>;
解绑服务标识符然后为其创建新绑定的便捷方法。这相当于调用 await container.unbind(serviceId) 然后调用 container.bind(serviceId),但在单个方法中。返回绑定构建器以继续配置新绑定。
const container: Container = new Container();
// Create initial binding
container.bind<Weapon>('Weapon').to(Katana);
// Get instance of Katana
const katana: Weapon = container.get<Weapon>('Weapon');
console.log(katana.damage); // 10
// Rebind asynchronously to Shuriken
async function rebindWeapon() {
// First unbind the existing service
await container.unbind('Weapon');
// Then bind to the new service
container.bind<Weapon>('Weapon').to(Shuriken);
// Get instance of Shuriken
const shuriken: Weapon = container.get<Weapon>('Weapon');
console.log(shuriken.damage); // 8
}
// Call the async function
void rebindWeapon();
rebindSync
rebindSync<T>(serviceIdentifier: ServiceIdentifier<T>): BindToFluentSyntax<T>;
rebind 的同步版本。同步解绑服务标识符,然后为其创建新绑定。如果解绑操作是异步的,将抛出错误。返回绑定构建器以继续配置新绑定。
const container: Container = new Container();
// Create initial binding
container.bind<Weapon>('Weapon').to(Katana);
// Get instance of Katana
const katana: Weapon = container.get<Weapon>('Weapon');
console.log(katana.damage); // 10
// Rebind synchronously to Shuriken
// This returns a BindToFluentSyntax to continue configuring the binding
container.rebindSync<Weapon>('Weapon').to(Shuriken);
// Get instance of Shuriken
const shuriken: Weapon = container.get<Weapon>('Weapon');
console.log(shuriken.damage);
register
register(pluginConstructor: Newable): void;
注册插件以扩展容器的功能。插件必须扩展 @inversifyjs/plugin 中的 Plugin 类并遵守其构造函数签名。有关更多信息,请参阅 插件文档。
restore
restore(): void;
将容器状态恢复到上一个快照。有关更多信息,请参阅 文档。
snapshot
snapshot(): void;
保存容器的状态以便稍后使用 restore 方法恢复。有关更多信息,请参阅 文档。
unbind
unbind(identifier: BindingIdentifier | ServiceIdentifier): Promise<void>;
从容器中删除绑定。当传递:
- 服务标识符:删除绑定到该服务标识符的所有绑定
- 绑定标识符:删除与该标识符关联的特定绑定
这将导致 停用过程。
示例:通过标识符解绑绑定
const bindingIdentifier: BindingIdentifier = container
.bind('MyService')
.to(MyServiceImpl)
.getIdentifier();
// Later, unbind just this specific binding
await container.unbind(bindingIdentifier);
unbindAll
unbindAll(): Promise<void>;
删除此容器中绑定的所有绑定。这将导致 停用过程。
unbindSync
unbindSync(identifier: BindingIdentifier | ServiceIdentifier): void;
同步地从容器中删除绑定。此方法的工作方式类似于 unbind,但不返回 Promise。如果解绑操作是异步的(例如,由于停用处理程序),它将抛出错误。当你确信操作不涉及异步停用时,请使用此方法。
const container: Container = new Container();
// Create a binding
container.bind<Weapon>('Weapon').to(Katana);
// Check if it's bound
console.log(container.isBound('Weapon')); // true
// Synchronously unbind the service
container.unbindSync('Weapon');
// Verify it's unbound
console.log(container.isBound('Weapon'));
unload
unload(...modules: ContainerModule[]): Promise<void>;
删除模块添加的绑定和处理程序。这将导致 停用过程。 请参阅 ContainerModule API 文档。
unloadSync
unloadSync(...modules: ContainerModule[]): void;
unload 的同步版本。删除模块添加的绑定和处理程序。如果任何模块卸载是异步的,将抛出错误。这将导致 停用过程。
请参阅 ContainerModule API 文档。
GetOptions
可以传递给 get、getAll、getAsync 和 getAllAsync 方法的选项。
interface GetOptions {
autobind?: boolean;
name?: MetadataName;
optional?: boolean;
tag?: GetOptionsTagConstraint;
}
autobind(boolean):自动将未绑定的类服务绑定到自身的选项。name(MetadataName):用于匹配绑定的名称元数据。optional(boolean):如果为 true,则如果未找到绑定,该方法将返回undefined或空数组。tag(GetOptionsTagConstraint):用于匹配绑定的标签元数据。
OptionalGetOptions
当结果是可选时,可以传递给 get 和 getAsync 方法的选项。
interface OptionalGetOptions extends GetOptions {
optional: true;
}
optional(true):指示结果是可选的,如果未找到绑定,该方法将返回undefined。
IsBoundOptions
可以传递给 isBound 和 isCurrentBound 方法的选项。
interface IsBoundOptions {
name?: MetadataName;
tag?: GetOptionsTagConstraint;
}
name(MetadataName):用于匹配绑定的名称元数据。tag(GetOptionsTagConstraint):用于匹配绑定的标签元数据。
GetAllOptions
可以传递给 getAll 和 getAllAsync 方法的选项。
interface GetAllOptions extends GetOptions {
chained?: boolean;
}
chained(boolean):启用跨容器层级结构的链式解析的选项。有关更多信息,请参阅 文档。