前言
上文介绍了如何理解依赖注入和控制反转,简单来说,控制反转是一种设计模式,可以将类与类的关系解耦,将人工维护转移给一个容器维护。要实现控制反转,依赖注入是一个常用方案,将依赖注册到 DI 容器中,哪里用到,就让容器将实例注入到哪里。
Nest 中的依赖注入,主要就是围绕提供者(Provider)展开。所谓的依赖,指的就是提供者类。本文通过一个简单示例,来演示 Nest 中的依赖注入是如何工作的(不涉及实现原理),主要分为三个步骤:
- 定义提供者
- 注册提供者
- 使用提供者
定义提供者
从代码上看,Nest 中的提供者 Provider,就是一个应用了 @Injectable()
装饰器的类,比如:
import { Injectable } from '@nestjs/common';
@Injectable()
export class UserService { // UserService 类就是一个提供者
findAllUsers() {
// ......
}
}
@Injectable()
装饰器的作用就是将提供者(比如这里的 UserService)作为依赖注册到 DI 容器中。之后当需要用到此提供者时,由 DI 容器负责完成实例化,并注入到需要的类中,从而将类与类之间的关系解耦。
注册提供者
上面只是定义了一个提供者,要使用提供者,还需要注册提供者。在一个模块定义中,比如 UserModule,在 @Module()
装饰器的 providers
属性中注册。
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
@Module({
providers: [UserService],
controllers: [UserController]
})
export class UserModule {}
providers
属性是注册提供者的列表,Nest 注入器或者说是DI 容器会将这里的提供者进行实例化, 并且这些提供者在该模块内都是可共享的。
这里的 providers
其实是一种简写形式,完整的写法是:
providers: [
{
provide: UserService,
useClass: UserService,
},
];
provide
属性的值是一个标识符(inject token),DI 容器使用这个 token 来标识注册的提供者,在使用时也是根据此 token 来找到提供者。默认的话,如果只传了一个提供者的类,则 token 的值就是这个类。这一点很重要。
使用提供者
从提供者所发挥的作用上看,它就是能对外提供一些方法的类,供其他类使用。比如上面定义的 UserService,它的作用就是提供一些操作用户的逻辑,在 UserController 控制器类中使用:
import { Controller, Get } from '@nestjs/common';
import { UserService } from './user.service';
@Controller('users')
export class UserController {
constructor(private userService: UserService) {}
@Get()
async getAllUsers() {
return this.userService.findAllUsers();
}
}
上面的示例中,在 UserController 类中要使用 UserService 类中的方法,无需自己实例化,而是在构造函数中使用了一个类型标识:
constructor(private userService: UserService) {}
Nest 的 DI 容器就能根据 “UserService” 找到此依赖项,也就是在模块定义中注册的提供者 UserService 类,然后创建实例并返回给构造函数使用。这就是依赖注入,同时这也实现了 UserController 类和 UserService 类之间的解耦,交给由 DI 容器去维护。
总结
上述的过程,就是 Nest 中一个完整的依赖注入的过程,总结一下就是:
- 使用
@Injectable()
装饰器将一个类定义为提供者 - 在模块类中的
@Module()
中使用providerss
注册提供者 - 在控制器中的构造函数中,通过注册提供者时的 token ,DI 容器将找到的提供者实例返回
如果有描述不准确之处,欢迎在评论区指出,感谢阅读。
标签:容器,依赖,DI,提供者,Nestjs,注册,Provider,UserService From: https://blog.51cto.com/u_12382805/8853348