0Pricing
TypeScript Academy · 课时

构造函数注入

通过构造函数以清晰的方式注入依赖。

构造函数注入 是 CoddyKit 上的免费 TypeScript Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 TypeScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 TypeScript Academy 课程共包含 4 节课。

深入了解构造函数注入

构造函数注入会将每个依赖项声明为构造函数参数。对象从创建之时起就已完成连接,因此不可能忘记必需的协作者。

参数属性

TypeScript 可以通过在参数上使用访问修饰符,在一个步骤中声明并赋值依赖项。private readonly 会自动创建并赋值该字段。

interface Mailer { send(to: string, body: string): void; }
class Notifier {
  constructor(private readonly mailer: Mailer) {}
}

基于接口的依赖项

依赖接口而不是类,可以将使用者与任何特定实现解耦。只要对象符合该接口,就可以将其提供出去。

interface Mailer { send(to: string, body: string): void; }
class SmtpMailer implements Mailer {
  send(to: string, body: string) { console.log("SMTP ->", to); }
}

在组合根处连接依赖项

创建对象图的位置称为组合根。您可以在那里选择具体实现并注入它们。

class Notifier {
  constructor(private readonly mailer: Mailer) {}
  notify(to: string) { this.mailer.send(to, "hello"); }
}
const app = new Notifier(new SmtpMailer());
app.notify("a@b.com");

替换实现

由于依赖项是接口,您可以提供完全不同的实现,而无需修改 Notifier。这正是 DI 提供的核心灵活性。

class FakeMailer implements Mailer {
  sent: string[] = [];
  send(to: string) { this.sent.push(to); }
}
const fake = new FakeMailer();
new Notifier(fake).notify("x@y.com");
console.log(fake.sent); // ["x@y.com"]

不进行真实输入/输出操作的测试

注入 fake 邮件发送器后,测试可以断言原本会发送的内容,而不会真正发送电子邮件。测试快速、确定且相互隔离。

const fake = new FakeMailer();
new Notifier(fake).notify("test@site");
console.log(fake.sent.length === 1); // true

多个依赖项

您可以列出所需的任意数量的依赖项。每个依赖项都明确、有类型且必需,使类的需求一目了然。

interface Logger { log(m: string): void; }
class Notifier {
  constructor(
    private readonly mailer: Mailer,
    private readonly logger: Logger,
  ) {}
}

readonly 防止重新赋值

将注入的字段标记为 readonly,可以防止它们在对象生命周期中途被替换,从而使对象的协作者保持稳定且可预测。

class Notifier {
  constructor(private readonly mailer: Mailer) {}
  // this.mailer = ... would be a compile error
}

内部不隐藏对象创建

使用构造函数注入的类不应在内部使用 new 创建协作者。所有依赖项都应通过构造函数传入,使耦合关系明确。

必需与可选

必需的依赖项应放在构造函数中。真正可选的依赖项可以默认为空操作实现,但仍应传入,而不是在内部创建。

const noopLogger: Logger = { log() {} };
new Notifier(new SmtpMailer(), noopLogger);

优势总结

构造函数注入可以明确依赖项,使对象完成初始化、实现可替换,并让测试变得简单。它成为默认的 DI 方式是有充分理由的。

快速检查

快速检查本课内容。

回顾

构造函数注入会将依赖项声明为参数(通常使用 private readonly),并通过接口为其添加类型。组合根选择具体实现;测试传入测试替身。对象始终完成连接,协作者也可以在不编辑类的情况下替换。

常见问题解答

「构造函数注入」课时是免费的吗?

是的 — 「构造函数注入」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 TypeScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 TypeScript Academy 课程共包含 4 节课。

「构造函数注入」这节课中我会学到什么?

通过构造函数以清晰的方式注入依赖。 你通过在浏览器中直接运行的动手代码来练习 TypeScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 TypeScript Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 TypeScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「构造函数注入」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 TypeScript Academy 课中编写并运行代码吗?

能。每节 TypeScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 控制反转基础
  2. 构造函数注入
  3. 使用 InversifyJS 的 DI 容器
  4. 类型安全的服务令牌
← 返回 TypeScript Academy