TypeScript中的依赖注入:初学者简易指南

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

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

开始课程

引言:什么是依赖注入,为什么需要它?

在软件开发的世界中,我们经常遇到一个类(或模块)依赖于另一个类的情况。例如,UserService类可能会使用DatabaseService类来保存数据。传统的方法是在UserService内部直接创建DatabaseService的实例。这会导致代码高度耦合,从而增加测试、维护和扩展的难度。

依赖注入(DI)是一种解决此问题的设计模式。它不是在类内部创建依赖关系,而是从外部“注入”它们。这实现了控制反转(IoC)原则:不是类管理其依赖关系,而是外部代码(容器或调用方)提供它们。

在本文中,我们将通过简单的示例,讲解如何在TypeScript中实现依赖注入。您将了解为什么DI被认为是一种良好实践,以及它如何帮助编写干净、可测试的代码。



问题:没有DI的紧耦合

让我们从一个示例开始,展示不应该怎样编写代码。假设我们有一个向用户发送通知的应用程序。

// 没有依赖注入class EmailService {    sendEmail(to: string, message: string): void {        console.log(`发送邮件至 ${to}: ${message}`);        // ... 实际的发送逻辑    }}

class NotificationService { private emailService: EmailService;

constructor() { // 问题:紧耦合 this.emailService = new EmailService(); }

notifyUser(userEmail: string, message: string): void { this.emailService.sendEmail(userEmail, message); }}

// 使用const notifier = new NotificationService();notifier.notifyUser('user@example.com', 'Hello!');

在这段代码中,NotificationService与EmailService紧密耦合。如果我们想要发送短信或推送通知怎么办?那就必须修改NotificationService的代码。此外,测试NotificationService也很困难——我们无法将真实的EmailService替换为模拟对象。



解决方案:通过构造函数注入依赖

实现DI最简单、最常用的方法是通过构造函数传递依赖关系。这使得代码灵活且易于测试。

首先,为我们的通知服务定义一个接口。这是关键的一步:我们在抽象层面编程,而不是具体的实现。

// 为任何通知服务定义接口interface INotificationService {    send(to: string, message: string): void;}

// 邮件实现class EmailService implements INotificationService { send(to: string, message: string): void { console.log(`[EMAIL] 发送至 ${to}: ${message}`); }}

// 短信实现class SMSService implements INotificationService { send(to: string, message: string): void { console.log(`[SMS] 发送至 ${to}: ${message}`); }}

// 使用DI的类class UserNotifier { private notifier: INotificationService;

// 通过构造函数注入依赖 constructor(notifier: INotificationService) { this.notifier = notifier; }

notifyUser(userContact: string, message: string): void { this.notifier.send(userContact, message); }}

// 使用const emailNotifier = new UserNotifier(new EmailService());emailNotifier.notifyUser('alice@example.com', '您的订单已准备好!');

const smsNotifier = new UserNotifier(new SMSService());smsNotifier.notifyUser('+7-999-123-45-67', '验证码:1234');

现在,UserNotifier不知道具体使用的是哪个服务

博客

书籍推荐