跳到主要内容
版本:Next

依赖注入层级

InversifyJS 是一个流行的库,用于在 TypeScript 应用程序中实现控制反转 (IoC) 和依赖注入 (DI)。它支持分层依赖注入,这在复杂的应用程序中是一个强大的工具。

使用 InversifyJS 的分层注入系统,你可以创建一个容器层级结构,其中每个容器都可以有一个父容器。这允许在你的应用程序中更好地组织和分离关注点。

当需要注入依赖项时,InversifyJS 首先在当前容器中查找绑定。如果未找到绑定,它将向上移动到父容器并继续搜索。此过程一直持续到找到绑定或到达顶级父容器为止。

绑定覆盖

找到的绑定可能会覆盖祖先绑定,即使不满足它们的约束。例如,如果在子容器中找到了请求服务的命名绑定,则该绑定将覆盖父绑定,即使该绑定后来在非命名解析请求中被丢弃。

DI 层级和缓存绑定

使用分层注入时,请注意,第一次解析的缓存绑定将用于后续解析,即使调用来自另一个子容器。

@injectable()
class Samurai {
constructor(
@inject(Katana)
public katana: Katana,
) {}
}

const parentContainer: Container = new Container();
parentContainer.bind(Samurai).toSelf().inSingletonScope();
parentContainer.bind(Katana).toSelf();

const childContainer: Container = new Container({ parent: parentContainer });
childContainer.bind(Katana).to(LegendaryKatana);

// The result of this resolution will be cached in the samurai binding
childContainer.get(Samurai);

// This samurai will have a LegendaryKatana injected
const samurai: Samurai = parentContainer.get(Samurai);

如果不希望这种行为,请考虑改用 ContainerModule。这样,你可以在两个容器中加载它。不同的容器将具有不同的绑定,因此具有不同的缓存值。

通过使用 InversifyJS 的分层注入系统,你可以轻松管理复杂的依赖关系,并保持代码整洁和模块化。它为处理 TypeScript 应用程序中的依赖关系提供了灵活且可扩展的解决方案。

class Katana {}

const parentContainer: Container = new Container();
parentContainer.bind(weaponIdentifier).to(Katana);

const childContainer: Container = new Container({ parent: parentContainer });

const katana: Katana = childContainer.get(weaponIdentifier);

链式解析模式

在处理容器层级结构时,InversifyJS 支持两种不同的解析模式:标准解析链式解析

标准解析模式

在标准解析模式(默认行为)下,InversifyJS 遵循首次发现的方法:

  1. 首先,它在当前容器中搜索绑定
  2. 如果在当前容器中找到绑定,则仅使用这些绑定
  3. 如果在当前容器中未找到绑定,则向上移动到父容器
  4. 此过程一直持续到找到绑定或到达顶级容器为止

这意味着,如果子容器对某个服务有任何绑定,则父容器对同一服务的绑定将被完全忽略:

const parentContainer: Container = new Container();

const container: Container = new Container({
parent: parentContainer,
});

parentContainer.bind<Weapon>('Weapon').to(Katana);
container.bind<Weapon>('Weapon').to(Shuriken);

// returns Weapon[] with only a Shuriken instance
const weapons: Weapon[] = container.getAll<Weapon>('Weapon', {
chained: false,
});

链式解析模式

链式解析模式允许你从容器层级结构的所有级别收集绑定。当使用带有 chained: true 选项的 getAll()getAllAsync() 时:

  1. 从当前容器收集绑定
  2. 然后从父容器收集绑定
  3. 这将递归地向上继续整个层级结构
  4. 所有收集到的绑定将被合并并返回

当你想要聚合来自应用程序不同层的服务(例如,来自父容器的核心服务和来自子容器的特定于功能的服务)时,这特别有用。

const parentContainer: Container = new Container();

const container: Container = new Container({
parent: parentContainer,
});

parentContainer.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', { chained: true });