文檔: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 { }