NestJS设计思想

nest 原理分析

nest 框架有一个非常典型的特征,就是大量使用了依赖注入的思想,那么之前没有后台开发经验或者没接触过这种设计思想的人(比如说我),看到这种写法之后肯定比较懵逼,非常想知道其中是如何实现的。虽然之前也一直有看过一些依赖注入、控制反转、装饰器、AOP 切面编程的思想等等,但是由于一直没有实践过,了解的并不是十分清楚。

刚好在开发 nest 的 exception 全局异常过滤器工具包的时候,遇到了一个问题,yarn link 开发的 nest 工具包之后,发现其中的依赖注入部分并没有生效,如下所示的使用方法:

1
2
3
4
5
6
7
8
9
10
11
12
@Catch(CustomException)
export class CustomExceptionFilter implements ExceptionFilter {
constructor(
@Optional() @Inject(INFRA_LOGNAME) private logger: IExceptionLogger
) {
this.logger = this.logger || new LoggerService();
}

catch(exception: CustomException, host: ArgumentsHost) {
// ...
}
}

基于这个原因,决定了解学习一下依赖注入原理,不然连排查问题的思路都没有,debug 都不知道这是个啥东西。

控制反转(IoC)和依赖注入(DI)

要分析 nest 的原理,那么必须要知道什么是 Ioc 和 DI,控制反转和依赖注入其实说的是一个东西,只不过站在不同的角度看的。控制反转是一种思想,依赖注入是一种设计模式。这里有一篇文章分析的很好Angular 2 DI - IoC & DI - 1,虽然是 Angular 的,但是很清楚的解释了两者的概念。

这种设计思想有什么用?最关键的就是能设计出更加松散、低耦合的程序。为什么这样讲,我们后面会有 demo 来分析。

控制反转(Ioc)

控制反转即将设计好的对象交给容器控制,而不是传统的由对象内部控制。

谁控制谁,控制什么: 在传统的程序设计中,我们直接在对象内部通过 new 的方式创建对象,是程序主动创建依赖对象;而 IoC 是有专门一个容器来创建这些对象,即由 IoC 容器控制对象的创建;谁控制谁?当然是 IoC 容器控制了对象;控制什么?主要是控制外部资源获取。

为何是反转了,哪些方面反转了: 有反转就有正转,传统应用程序是由我们自己在对象中主动控制去获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转了;哪些方面反转了?依赖对象的获取被反转了。

依赖注入

DI - Dependency Injection,即”依赖注入”:组件之间的依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

参考文章