NestJs 提供者
文档:https://docs.nestjs.cn/9/providers
Providers 是 Nest 的一个基本概念。
许多基本的 Nest 类可能被视为
provider - service, repository, factory, helper 等等。
他们都可以通过 constructor 注入依赖关系。
这意味着对象可以彼此创建各种关系,
并且“连接”对象实例的功能在很大程度上可以委托给 Nest运行时系统。
Provider 只是一个用 @Injectable() 装饰器注释的类。
基本用法
如: 我们通过
nest g resource user
创建的user 模块
user.service.ts
import { Injectable } from '@nestjs/common';
// 提供者:Provider 只是一个用 @Injectable() 装饰器注释的类。
@Injectable()
export class UserService {}
module 里面已经引入 service 在 providers 注入
import { Module } from '@nestjs/common';
// 引入service
import { UserService } from './user.service';
@Module({
// 提供者注入
providers: [UserService]
})
export class UserModule {}
在Controller 可以使用注入好的 Service 了
import { Controller } from '@nestjs/common';
// 引入service
import { UserService } from './user.service';
@Controller('user')
export class UserController {
constructor(
// 注入service
private readonly userService : UserService
){}
}
service 第二种用法 自定义名称
第一种用法就是一个语法糖
在 NestJs 中,默认情况下,服务名称是与服务类名相同的字符串。如果我们需要自定义服务名称,可以在 @Injectable()
装饰器中使用 provide
属性指定服务名称。
其实他全称是这样的
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
@Module({
controllers: [UserController],
providers: [{
provide: 'makalo_test',
useClass: UserService
}]
})
export class UserModule {}
自定义名称之后 需要用对应的@inject 取 不然找不到
constructor(@Inject('makalo_test') private readonly userService: UserService) {}
自定义注入值
module.ts
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
@Module({
controllers: [UserController],
providers: [
{
provide: 'makalo_test',
useClass: UserService
},
{
provide: "JD",
useValue: ['TB', 'PDD', 'MT', 'ELM']
}
]
})
export class UserModule { }
controller.ts
import { Controller, Get, Post, Body, Patch, Param, Delete, Inject } from '@nestjs/common';
import { UserService } from './user.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
@Controller('user')
export class UserController {
constructor(
@Inject('makalo_test') private readonly userService: UserService,
// 自定义注入的值
@Inject('JD') private readonly shopList:string[]
) {}
@Post()
create(@Body() createUserDto: CreateUserDto) {
return this.userService.create(createUserDto);
}
@Get()
findAll() {
// 使用
return this.userService.findAll() + this.shopList;
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.userService.findOne(+id);
}
@Patch(':id')
update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
return this.userService.update(+id, updateUserDto);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.userService.remove(+id);
}
}
工厂模式
如果服务 之间有相互的依赖 或者逻辑处理 可以使用 useFactory
例:
我们将user.service 复制两份,分别命名为user.service2 和 3
将 2 和 3 的类名改下,并将3的构造函数增加参数
constructor(userService2:UserService2){
}
module 里面注入
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { UserService2 } from './user.service2';
import { UserService3 } from './user.service3';
@Module({
controllers: [UserController],
providers: [
{
provide: 'makalo_test',
useClass: UserService
},
{
provide: "JD",
useValue: ['TB', 'PDD', 'MT', 'ELM']
},
UserService2,
{
provide: "TestFactory",
inject: [UserService2],
useFactory(UserService2: UserService2) {
return new UserService3(UserService2)
}
}
]
})
export class UserModule { }
控制器里面使用
// 工厂模式
@Inject('TestFactory') private readonly testFactory:UserService3
异步模式
useFactory 返回一个promise 或者其他异步操作
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { UserService2 } from './user.service2';
import { UserService3 } from './user.service3';
@Module({
controllers: [UserController],
providers: [
{
provide: 'makalo_test',
useClass: UserService
},
{
provide: "JD",
useValue: ['TB', 'PDD', 'MT', 'ELM']
},
UserService2,
{
provide: "TestFactory",
inject: [UserService2],
useFactory(UserService2: UserService2) {
return new UserService3(UserService2)
}
},
{
provide: "sync",
async useFactory() {
return await new Promise((r) => {
setTimeout(() => {
r('sync')
}, 3000)
})
}
}
]
})
export class UserModule { }