本篇文章带大家了解一下Node 后端框架Nest.js , 介绍一下Nestjs模块机制的概念和实现原理 , 希望对大家有所帮助!
文章插图
Nest 提供了模块机制 , 通过在模块装饰器中定义提供者、导入、导出和提供者构造函数便完成了依赖注入 , 通过模块树组织整个应用程序的开发 。 按照框架本身的约定直接撸一个应用程序 , 是完全没有问题的 。 可是 , 于我而言对于框架宣称的依赖注入、控制反转、模块、提供者、元数据、相关装饰器等等 , 觉得缺乏一个更清晰系统的认识 。
好像能够理解 , 能够意会 , 但是让我自己从头说清楚 , 我说不清楚 。 于是进行了一番探索 , 便有了这篇文章 。 从现在起 , 我们从新出发 , 进入正文 。为什么需要控制反转?什么是依赖注入?装饰器做了啥?模块 (@Module) 中的提供者(providers) , 导入(imports)、导出(exports)是什么实现原理?
1 两个阶段1.1 Express、Koa
一个语言和其技术社区的发展过程 , 一定是从底层功能逐渐往上丰富发展的 , 就像是树根慢慢生长为树枝再长满树叶的过程 。 在较早 , Nodejs 出现了 Express 和 Koa 这样的基本 Web 服务框架 。 能够提供一个非常基础的服务能力 。 基于这样的框架 , 大量的中间件、插件开始在社区诞生 , 为框架提供更加丰富的服务 。 我们需要自己去组织应用依赖 , 搭建应用脚手架 , 灵活又繁琐 , 也具有一定工作量 。
发展到后面 , 一些生产更高效、规则更统一的框架便诞生了 , 开启了一个更新的阶段 。
1.2 EggJs、Nestjs
为了更加适应快速生产应用 , 统一规范 , 开箱即用 , 便发展出了 EggJs、NestJs、Midway等框架 。 此类框架 , 通过实现底层生命周期 , 将一个应用的实现抽象为一个通用可扩展的过程 , 我们只需要按照框架提供的配置方式 , 便可以更简单的实现应用程序 。 框架实现了程序的过程控制 , 而我们只需要在合适位置组装我们的零件就行 , 这看起来更像是流水线工作 , 每个流程被分割的很清楚 , 也省去了很多实现成本 。
1.3 小结
上面的两个阶段只是一个铺垫 , 我们可以大致了解到 , 框架的升级是提高了生产效率 , 而要实现框架的升级 , 就会引入一些设计思路和模式 , Nest 中就出现了控制反转、依赖注入、元编程的概念 , 下面我们来聊聊 。
2 控制反转和依赖注入2.1 依赖注入
一个应用程序实际就是非常多的抽象类 , 通过互相调用实现应用的所有功能 。 随着应用代码和功能复杂度的增加 , 项目一定会越来越难以维护 , 因为类越来越多 , 相互之间的关系越来越复杂 。
举个例子 , 假如我们使用 Koa 开发我们的应用 , Koa 本身主要实现了一套基础的 Web 服务能力 , 我们在实现应用的过程中 , 会定义很多类 , 这些类的实例化方式、相互依赖关系 , 都会由我们在代码逻辑自由组织和控制 。 每个类的实例化都是由我们手动 new , 并且我们可以控制某个类是只实例化一次然后被共享 , 还是每次都实例化 。 下面的 B 类依赖 A , 每次实例化 B 的时候 , A 都会被实例化一次 , 所以对于每个实例 B 来说 , A 是不被共享的实例 。
class A{}// Bclass B{ contructor(){ this.a = new A(); }}下面的 C 是获取的外部实例 , 所以多个 C 实例是共享的 app.a 这个实例 。
class A{}// Cconst app = {};app.a = new A();class C{ contructor(){ this.a = app.a; }}下面的 D 是通过构造函数参数传入 , 可以每次传入一个非共享实例 , 也可以传入共享的 app.a 这个实例(D 和 F 共享 app.a) , 并且由于现在是参数的方式传入 , 我也可以传入一个 X 类实例 。
class A{}class X{}// Dconst app = {};app.a = new A();class D{ contructor(a){ this.a = a; }}class F{ contructor(a){ this.a = a; }}new D(app.a)new F(app.a)new D(new X())这种方式就是依赖注入 , 把 B 所依赖的 A , 通过传值的方式注入到 B 中 。 通过构造函数注入(传值)只是一种实现方式 , 也可以通过实现 set 方法调用传入 , 或者是其他任何方式 , 只要能把外部的一个依赖 , 传入到内部就行 。 其实就这么简单 。
class A{}// Dclass D{ setDep(a){ this.a = a; }}const d = new D()d.setDep(new A())2.2 All in 依赖注入?
随着迭代进行 , 出现了 B 根据不同的前置条件依赖会发生变化 。 比如 , 前置条件一
this.a
需要传入 A 的实例 , 前置条件二this.a
需要传入 X 的实例 。 这个时候 , 我们就会开始做实际的抽象了 。 我们就会改造成上面 D 这样依赖注入的方式 。
推荐阅读
- 剑与远征8月26日兑换码分享-8月兑换码大全您需要了解的
- 帕斯卡契约星环之坠图鉴-星环之坠战利品介绍您需要了解的
- 养胃的一些禁忌你得了解 饥一顿饱一顿最易致胃病
- 小编详解win7正版多少钱新系统了解的东西
- 任务栏颜色,图文告诉您如何更改任务栏颜色新系统了解的东西
- Win7鼠标右键失效不能复制粘贴怎么办?小编教你新系统了解的东西
- 分享写优秀文案的5种方法 写优秀文案的方法有哪些?
- word打不开发送错误报告怎么办 word弹出错误报告解决方法新系统了解的东西
- Win7系统任务栏变宽变窄怎么还原?小编教你新系统了解的东西
- 网络不稳定是什么原因?小编教你Win7网络不稳定的解决方法新系统了解的东西