tsyringe TypeScript 依赖注入:完整教程与实战示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

tsyringe TypeScript 依赖注入:完整教程与实战示例

在现代 TypeScript 开发中,依赖管理是构建可扩展、可测试应用的关键任务之一。tsyringe 是一个轻量级且功能强大的依赖注入(Dependency Injection, DI)容器,完全基于 TypeScript 装饰器构建。它允许开发者以声明式方式描述组件间的依赖关系,自动解析这些依赖,并管理对象的生命周期。

为什么需要 tsyringe?在大型项目中,手动创建类实例并将其传递给构造函数会导致代码高度耦合,增加测试难度,并阻碍实现的替换。tsyringe 通过提供一个集中式注册表(容器)来解决这些问题,该容器知道如何创建和提供依赖。你只需指定哪些类或令牌需要注册,容器就会自动将它们注入到需要的地方。这使代码更简洁、更模块化,并大大简化了单元测试的编写。

该库积极使用 TypeScript 装饰器(@injectable()、@inject()),使得熟悉 Angular 或 NestJS 的开发者能够直观理解其语法。tsyringe 无需复杂配置,开箱即用,支持现代 TypeScript 版本,并提供多种注册策略(singleton、transient、scoped)。本文将详细解析 tsyringe 的各个方面,从安装到高级使用场景。

安装

要在你的 TypeScript 项目中安装 tsyringe,请使用 npm 执行以下命令:

npm install tsyringe reflect-metadata

安装后,需要确保项目已配置装饰器支持。为此,在 tsconfig.json 文件中启用以下选项:

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

此外,在应用的入口点(例如 index.ts)中,需要一次性导入 reflect-metadata 以启用装饰器的元数据:

import "reflect-metadata";
// ... 其余代码

快速上手:最小化工作示例

让我们创建一个简单的应用,演示 tsyringe 的基本机制。我们将有一个数据库服务,它被注入到控制器中。

import "reflect-metadata";
import { container, injectable, inject } from "tsyringe";

// 1. 定义将被注入的服务
@injectable()
class DatabaseService {
  getData(): string {
    return "来自数据库的数据";
  }
}

// 2. 定义依赖于 DatabaseService 的控制器
@injectable()
class UserController {
  constructor(
    @inject(DatabaseService) private dbService: DatabaseService
  ) {}

  getUserData(): string {
    return this.dbService.getData();
  }
}

// 3. 在容器中注册类(此处非必需,因为 tsyringe 可自动解析已注册的类)
container.registerSingleton(DatabaseService);
container.registerSingleton(UserController);

// 4. 使用容器获取控制器实例
const controller = container.resolve(UserController);
console.log(controller.getUserData()); // 输出:"来自数据库的数据"

此示例展示了三个关键步骤:将类标记为 @injectable(),通过构造函数中的 @inject() 指定依赖,以及通过 container.resolve() 获取实例。请注意,如果类已通过装饰器注册,则无需显式调用 registerSingleton。

推荐