视频教程
08_nest-provider1_哔哩哔哩_bilibili
前言
在 Nest.js 框架中,Providers 是一个核心概念,用于定义和管理应用中的服务、数据库连接、中间件、门面(facade)、仓库(repository)、工厂(factory)、帮助器(helper)等可注入的依赖。Providers 是 Nest.js 实现依赖注入(Dependency Injection, DI)体系的基础单元,它们可以被其他组件通过构造函数、属性注入等方式依赖,并由 Nest.js 的依赖注入容器自动管理和实例化。
arduino
nest new provider -p pnpm
sql
pnpm start:dev
1. 基本用法
可以看到 AppService 是被 @Injectable 修饰的 class
在 Module 的 providers 里声明,在 AppController 的构造器里参数里声明了 AppService 的依赖,就会自动注入。
如果不想用构造器注入,也可以属性注入:
还可以
2. providers第二种用法(自定义名称)
第一种用法就是一个语法糖
其实他的完整写法是这样的
php
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [{
provide: AppService,
useClass: AppService,
}],
})
export class AppModule { }
通过 provide 指定 token,通过 useClass 指定对象的类,Nest 会自动对它做实例化后用来注入。
当然,这个 token 也可以是字符串(不一定为app_service,你可以自定义为任何名称)
如果 token 是字符串的话,注入的时候就要用 @Inject 手动指定注入对象的 token 了
相比之下,用 class 做 token 可以省去 @Inject,比较简便。
3. 自定义注入值
除了指定 token 外,还可以直接指定一个值,让 IoC 容器来注入
php
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [
{
provide: 'app_service',
useClass: AppService,
},
{
provide: 'person',
useValue: {
name: 'xt',
age: 18
}
}
],
})
export class AppModule { }
使用 provide 指定 token,使用 useValue 指定值。然后再注入它
4. 工厂模式
在 Nest.js 中,useFactory 是一种特殊的提供商配置方式,它允许你在运行时动态创建一个服务实例,而不是直接实例化一个类
4.1. 动态配置加载: 当你需要从环境变量、配置文件或其他非静态来源获取配置数据时,可以使用 useFactory 创建一个返回配置对象的工厂函数
ini
API_URL = xxx
API_KEY = xt
arduino
pnpm install @nestjs/config
在app.module.ts中使用
在app.controller中注入
4.2. 如果服务 之间有相互的依赖 或者逻辑处理 可以使用 useFactory
php
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
envFilePath: ['.env'],
}),
],
controllers: [AppController],
providers: [
{
provide: 'app_service',
useClass: AppService,
},
{
provide: 'person',
useValue: {
name: 'xt',
age: 18
}
},
{
provide: 'app_config',
useFactory: () => ({
apiUrl: process.env.API_URL,
apiKey: process.env.API_KEY,
}),
},
AppService,
{
provide: 'app_test',
inject: [AppService],
useFactory(appService: AppService) {
return {
name: 'xt',
desc: appService.getHello()
}
},
}
],
})
export class AppModule { }
app_test 中要inject: [AppService], 所以我们得先在providers提供 AppService
5. 异步模式
useFactory 返回一个promise 或者其他异步操作
javascript
{
provide: "sync",
useFactory: async () => {
return await new Promise((resolve) => {
setTimeout(() => {
resolve('sync')
}, 3000)
})
}
}
Nest 会等拿到异步方法的结果之后再注入
等3秒后
6. 别名
css
{
provide: 'new_person',
useExisting: 'person'
}
这里就是给 person 的 token 的 provider 起个新的 token 叫做 new_person。然后就可以用新 token 来注入了:
7. 总结
- 一般情况下,provider 是通过 @Injectable 声明,然后在 @Module 的 providers 数组里注册的 class。
- 默认的 token 是 class,这样不用使用 @Inject 来指定注入的 token。
- 可以用字符串类型的 token,不过注入的时候要用 @Inject 单独指定。
- 可以用 useClass 指定注入的 class,还可以用 useValue 直接指定注入的对象。
- 动态生成对象,或依赖其他服务 可以使用 useFactory
- 起别名,可以用 useExisting 给已有的 token,指定一个新 token