Nestjs一IOC和DI

65 阅读3分钟

前言

最近刚把nest学习完,从头回顾一下,很多理论知识都忘记了,光学习代码层面的知识了,所以打算从头开始在走一遍。

正文

Nestjs

官方描述:

Nest 是一个用于构建高效,可扩展的 Node.js 服务器端应用程序的框架。它使用渐进式 JavaScript,内置并完全支持 TypeScript(但仍然允许开发人员使用纯 JavaScript 编写代码)并结合了 OOP(面向对象编程),FP(函数式编程)和 FRP(函数式响应编程)的元素。

在底层,Nest使用强大的 HTTP Server 框架,如 Express(默认)和 Fastify。Nest 在这些框架之上提供了一定程度的抽象,同时也将其 API 直接暴露给开发人员。这样可以轻松使用每个平台的无数第三方模块。

简单理解:

Nest是一个nodejs框架,类似于egg、koa、express,只是提供更直接直观的API,其底层基于express,支持TypeScript。其0-1的过程比express更快更便捷。

核心概念

这里面有好几个概念,个人认为挺难理解的,只能说多看,然后结合实际慢慢理解。

最主要的两个概念: IoC(Inversion of Control 控制反转)和 DI(Dependency Injection 依赖注入)

首先二者并不是一个平级的关系。IoC是面向对象编程中的一种设计原则,一种设计理念,意思是减少代码之间的耦合度,它的具体实现方式就是依赖注入(Dependency Injection,简称DI),还有一种方式叫依赖查找(Dependency Lookup)。

以上是从官方角度理解。个人理解这两个概念其实就是一个东西,而且要理解这两个概念,最好是先入手框架的使用,从代码使用层面理解更容易一些。

总结:DI(方案)是IOC(理念)的具体实现

代码

import A from './modules/a';
import B from './modules/b';

// app.ts
class App {
  constructor(options) {
    this.options = options;

    this.a = new A();
    this.b = new B();
    // ... c

    this.initial();
  }

  initial() {
    // 具体的类的一些初始化实现操作
    this.options.init();
  }
}

// main.ts
new App({
  init() {
    ...
  },
});

如果我们从IOC层面去分析上面的代码,可以分析出:

类App对内部new的实例有很强的控制权(有业务逻辑),比如情况1我们要对实例A实现参数new A({x:'abc'}),意味着我们要修改类App,在比如情况2我们要新增一个C实例,还是要去修改类App。

怎么优化修改呢?情况一我们可以通过在 App 实例化的时候传入参数{x:'abc'},在直接点,我们直接传入new A({x:'abc'}),那么App内部就不用new了。情况二就是在情况一的基础上,我们传入一个数组,比如App.use([A,B,C,...]),通过遍历,告诉App,哪些模块需要注入,传入模块的过程就叫依赖注入,这样App类中只有公共的模块处理逻辑,没有各自模块中的业务逻辑,这个过程就是控制权的反转,将控制权从App中重新回到各自的模块。

nest中使用的底层库就是 reflect-metadata 这个包

大家可以看看这篇,里面就有上面说的过程的代码Nestjs 初探 - 理解 IoC 和 DI

安装nest

 // 全局安装Nest
npm i -g @nestjs/cli

// nest命令创建项目
nest new project-name 

待续