Nest 实现了 IOC 容器,会从入口模块开始扫描,分析 Module 之间的引用关系,对象之间的依赖关系,自动把 provider 注入到目标对象。
类提供者
最常用的形式,使用类本身作为提供者
这个类通常会有 @Injectable()
装饰器,表明它可以被注入:
使用 useClass 的 Provider
当你想要注入一个类,但是使用不同于通常实例化的类时,可以使用 useClass。
typescript
class MyService {
// ...
}
class MyMockService {
// ...
}
@Module({
providers: [
{
provide: MyService,
useClass: process.env.NODE_ENV === 'development' ? MyMockService : MyService,
},
],
})
export class MyModule {}
typescript
import { Injectable } from '@nestjs/common';
@Injectable()
class SomeService {
constructor(private myService: MyService) {}
someMethod() {
// 使用 this.myService 调用 MyService 或 MyMockService 的方法
}
}
其实之前写的 providers: [appService]
是一种简写,完整写法:
通过 provide 指定注入的 token,通过 useClass 指定注入的对象的类。
Nest 会自动将其实例化注入:
如果不想用构造器注入,也可以属性注入:
通过 @Inject 指定注入的 provider 的 token 即可。
这个 token 也可以是字符串:
值提供者
除了指定 class 外,还可以直接指定一个值,让 IOC 容器来注入。
工厂提供者
provider 的值可能是动态产生的,Nest 支持使用 useFactory 来动态创建一个对象:
useFactory 也是支持参数的注入的。
我们在 useFactory 通过 inject 声明了两个 token,一个是字符串 token 的 person,一个是 class token 的 AppService。
在调用 useFactory 方法的时候,Nest 就会注入这两个对象:
useFactory 还支持异步:
这样 Nest 就会等拿到异步方法的结果之后再注入,更灵活。
别名提供者
provider 还可以通过 useExisting 来指定别名:
这里给 asyncPerson 的 provider 起个新的 token 叫做 newPerson。