什么是依赖注入?

本篇是nestjs系列文章的番外篇,主要是介绍控制反转Invention of Control(IoC)和依赖注入Dependecy Injection(DI),作为nestjs和angular的核心概念,学习它们有利于更好的进行框架的学习。

定义

控制反转(Inversion of Control)是一种是面向对象编程中的一种设计原则,用来减低计算机代码之间的耦合度。其基本思想是:借助于“第三方”实现具有依赖关系的对象之间的解耦。

依赖注入是一种用于实现IoC的设计模式,它允许在类外创建依赖对象,并通过不同的方式将这些对象提供给类。使用DI,我们将依赖对象的创建和绑定移到依赖它们的类之外。具体的做法,比如:将实例变量传入到一个对象中去(Dependency injection means giving an object its instance variables)

简单来说它和依赖注入间的区别就是:

  • 控制反转是一种设计思想
  • 依赖注入是一种编程技巧

作用

先看个例子:我们希望在通知组件(NotificationComponent)中通过消息服务(MessageService)发送一条消息。

如果不使用依赖注入的话,我们的代码大概长这样:

1
2
3
4
5
6
7
8
9
class NotificationComponent {
msg: MessageService;
constructor() {
this.msg = new MessageService();
}
sendMsg(msgType: string, info: string) {
this.msg.send(msgType, info);
}
}

使用依赖注入时:

1
2
3
4
5
6
class NotificationComponent {
constructor(msg: MessageService) {} // Angular 中注入依赖的方式
sendMsg(msgType: string, info: string) {
this.msg.send(msgType, info);
}
}

经过对比,可以看到使用依赖注入有两个很显然的优点:

  • 代码的行数变少了
  • NotificationComponentMessageService 间的耦合性降低了

结论

在控制反转中,”控制“是指对程序流程的控制,”反转“则是将控制权从程序员的手里反转到了外层框架。

控制反转是一种在软件工程中解耦合的思想,调用类只依赖接口,而不依赖具体的实现类,减少了耦合。控制权交给了容器,在运行的时候才由容器决定将具体的实现动态的“注入”到调用类的对象中。

既然控制反转是一种设计思想,那么作为相应实现方式之一的依赖注入(模板模式也是种实现方式)必然也遵循此思想。

依赖注入是一种设计模式,可以作为控制反转的一种实现方式。依赖注入就是将实例变量传入到一个对象中去(Dependency injection means giving an object its instance variables)。

通过IoC框架,类A依赖类B的强耦合关系可以在运行时通过容器建立,也就是说把创建B实例的工作移交给容器,类A只管使用就可以。