控制反转(IOC)是一种编程思想,它改变了传统程序的执行流程。想象一下,传统程序像是你亲自开车,而IOC则像是坐公交。在IOC中,你不再亲自控制每个步骤,而是把控制权交给框架公交车,框架会帮你处理很多琐碎的事情,你只需专注于自己的目的地业务逻辑。比如Spring框架帮你管理对象、处理依赖关系,使代码更简洁、灵活
在后端的系统中 会有很多对象 比如Controller 对象(接收 http 请求,调用 Service,返回响应数据)、Service 对象(实现业务逻辑)、Repository 对象(实现对数据库的增删改查)、DataSource 对象(数据库链接)、 Config 对象 (配置对象 )这些对象之间的关系很复杂 且有些对象需要一系列的初始化之后吃能使用 有些对象不需要每次都new一个新的,而IoC就是用来解决这些痛点,Nest就是使用Ioc来实现的
NestJS是一个使用TypeScript构建的现代化Node.js框架。它使用了依赖注入(DI)和反转控制(IOC)的概念来管理应用程序的组件。
在NestJS中使用IOC的核心是使用依赖注入器来管理应用程序的依赖关系。依赖注入是指通过将依赖项传递给需要使用它们的类或组件来实现解耦。
以下是NestJS中使用IOC的一些常见方法:
- 使用装饰器和提供程序:NestJS提供了一些装饰器来标记类或组件作为提供程序。例如,使用
@Injectable()
装饰器标记类作为可注入的提供程序,使用@Inject()
装饰器将依赖项注入到类中。
@Injectable()
class MyService {
constructor(private readonly anotherService: AnotherService) {}
}
@Injectable()
class AnotherService {
// ...
}
- 使用模块定义依赖关系:使用NestJS的模块系统,可以定义应用程序的依赖关系。在模块中,可以使用
providers
属性定义提供程序,并使用imports
属性导入其他模块。
@Module({
imports: [AnotherModule],
providers: [MyService],
})
class AppModule {}
- 使用构造函数注入:在NestJS中,可以通过将依赖项作为构造函数的参数来实现依赖注入。依赖项将由NestJS的依赖注入器自动解析和注入。
@Injectable()
class MyService {
constructor(private readonly anotherService: AnotherService) {}
}
这些是使用NestJS中IOC的一些基本方法。通过使用这些方法,您可以轻松地管理和注入应用程序的依赖关系。
接下来我们创建一个真实nest项目来了解Nest项目是如何使用Ioc的
1、执行下面命令创建项目 (注意如果没有全局安装记得安装一下 详情请看第一篇)
nest new ioc
我这里选的是pnpm 大家可以根据自己的需求选择
接着进入这个命令执行 pnpm run start 启动服务
接着使用浏览器访问 http://localhost:3000 就可以看到 nest 服务返回的 hello world
我们可以看到下面代码 app.service.ts 中有个 AppService类里有个getHello()函数 返回了 ‘Hello World!’ 这就是我们界面显示的内容,它有一个 AppService 声明了 @Injectable,代表这个 class 可注入,那么 nest 就会把它的对象放到 IOC 容器里。
接着我们看看 app.controller.ts 文件 ,里面有一个AppController 声明了 @Controller ,代表这个类可以被注入nest 也会把它放到 IoC 容器里 且AppController 的构造器参数依赖了上面app.service.ts 的 AppService
到此 我们可能有个疑问 为什么 controller 和 service 要分开呢 ?
因为 service 是可以被注入也是可以注入到别的对象的,所以用 @Injectable 声明
controller 只需要被注入,所以 nest 单独给它加了 @Controller 的装饰器
我们可以看到下面的app.module.ts
@Module 是声明模块
其中 controllers 是控制器 只能被注入
providers 可以被注入,也可以注入别的对象
我们可以看一下入口文件 main.ts, nest 就会从 AppModule 开始解析 class 上通过装饰器声明的依赖信息,自动创建和组装对象。
nest 在背后自动做了对象创建和依赖注入的工作。