Providers
是Nest
中的一個基本概念,許多Nest
中定義的類都可以被視為一個Provider
,比如:service、repository、factory、helper等,它們都可以通過constructor
注入依賴關係,這就意味著類與類之間可以建立各種依賴關係,並且維護各個類之間依賴關係的工作將委託給Nest
執行時系統。
前面幾章我們通過nest-cli
生成的程式碼中就包含有service
類
比如:
// nanjiu.service.ts
import { Injectable } from '@nestjs/common';
import { CreateNanjiuDto } from './dto/create-nanjiu.dto';
import { UpdateNanjiuDto } from './dto/update-nanjiu.dto';
@Injectable()
export class NanjiuService {
create(createNanjiuDto: CreateNanjiuDto) {
return 'This action is nanjiu post';
}
findAll() {
return `This action returns all nanjiu`;
}
findOne(id: number) {
return `This action returns a #${id} nanjiu`;
}
update(id: number, updateNanjiuDto: UpdateNanjiuDto) {
return `This action updates a #${id} nanjiu`;
}
remove(id: number) {
return `This action removes a #${id} nanjiu`;
}
}
使用步驟如下:
這裡的NanjiuService
類通過@Injectable
裝飾器標記為一個provider
,表明該類可以被Nest
的IOC
容器管理
服務需要在對應的module
中進行註冊,如果不註冊IOC
容器是不會幫你建立物件的,而且還會報錯
// nanjiu.module.ts
@Module({
controllers: [NanjiuController],
providers: [NanjiuService]
})
export class NanjiuModule {}
在module
中註冊service
類後,再通過controller
的建構函式進行注入,那麼該類就可以在controller
中去使用了
// nanjiu.controller.ts
@Controller('nanjiu')
export class NanjiuController {
constructor(private readonly nanjiuService: NanjiuService) {}
@Post()
@Header('Cache-Control', 'none')
create(@Body() createNanjiuDto: CreateNanjiuDto) {
console.log('body', createNanjiuDto)
return this.nanjiuService.create(createNanjiuDto);
}
}
可以看到是通過類建構函式 constructor(private readonly nanjiuService: NanjiuService) {}
這種方式來進行依賴注入的,Nest提供了IOC
容器利用Typescript自帶型別的特點自動建立物件的能力,注意這裡是單例模式,如果該Service在其它地方也被用過,那麼會在不會重新建立物件,各個應用只會有一個該Service的物件,容器會先尋找當前有沒有,如果沒有再進行建立。
Provider
可以是一個值(value),也可以是一個類(class),還可以是一個工廠函數(factory)
上面providers
的那種寫法其實是一種簡寫,它的完整寫法應該是這樣:
// nanjiu.module.ts
@Module({
controllers: [NanjiuController], // 控制器
providers: [{
provide: 'NANJIU', // 自定義依賴注入的標識
useClass: NanjiuService // 依賴注入的類
}]
})
export class NanjiuModule {}
完整寫法可以通過provide
屬性給不同的provider
標註不同的token
然後再controller
中需要使用@Inject(對應的token)
進行注入
// nanjiu.controller.ts
@Controller('nanjiu')
export class NanjiuController {
constructor(@Inject('NANJIU') private readonly nanjiuService: NanjiuService) {}
@Post()
@Header('Cache-Control', 'none')
create(@Body() createNanjiuDto: CreateNanjiuDto) {
console.log('body', createNanjiuDto, this.nanjiuService)
return true
return this.nanjiuService.create(createNanjiuDto);
}
}
還可以使用useValue
自定義注入值
// nanjiu.module.ts
@Module({ // 模組裝飾器
controllers: [NanjiuController], // 控制器
providers: [{
provide: 'NANJIU', // 自定義依賴注入的標識
useValue: {
name: 'nanjiu' // 依賴注入的值
}
}]
})
工廠函數可以提供動態的provider
,由factory
函數的返回值來確定,factory
函數可以很簡單也可以很複雜,它也可以使用其它provider
,不過需要在inject
屬性進行注入,注入的provider
可以是可選的
工廠函數可以接受(可選)引數。
(可選)inject
屬性接受一組提供程式,Nest 將在範例化過程中解析這些提供程式並將其作為引數傳遞給工廠函數。這兩個列表應該是相關的:Nest 將以inject
相同的順序將列表中的範例作為引數傳遞給工廠函數。
// nanjiu.module.ts
import { Module } from '@nestjs/common';
import { NanjiuService } from './nanjiu.service';
import { UserService } from 'src/user/user.service';
import { NanjiuController } from './nanjiu.controller';
@Module({ // 模組裝飾器
controllers: [NanjiuController], // 控制器
providers: [{
provide: 'NANJIU', // 自定義依賴注入的標識
useClass: NanjiuService // 依賴注入的類
},
UserService,
{
provide: 'USER', // 自定義依賴注入的標識
useFactory: (...args) => { // 工廠模式
console.log('useFactory', args)
return new UserService() // 依賴注入的類
},
inject: [UserService] // 依賴注入的類
}
]
})
export class NanjiuModule {}
有時你可能存在不一定需要解決的依賴關係。例如,你的類可能依賴於設定物件,但如果沒有傳遞任何內容,則應使用預設值。在這種情況下,依賴關係變得可選,這時候可以給對應的注入服務再增加一個@Optional()
裝飾器就行
import { Injectable, Optional, Inject } from '@nestjs/common';
@Injectable()
export class HttpService<T> {
constructor(@Optional() @Inject('HTTP_OPTIONS') private httpClient: T) {}
}
useFactory
可以返回一個promise 或者其他非同步操作,Nest 將在範例化任何依賴(注入)此類提供程式的類之前等待promise
的結果。
// nanjiu.module.ts
@Module({ // 模組裝飾器
controllers: [NanjiuController], // 控制器
providers: [
UserService,
{
provide: 'USER', // 自定義依賴注入的標識
useFactory: async () => { // 工廠模式
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(new UserService())
}, 1000)
})
},
inject: [UserService] // 依賴注入的類
}
]
})
export class NanjiuModule {}
-------------------------------------------
如果這篇文章有幫助到你,❤️關注+點贊❤️鼓勵一下作者,文章公眾號首發,關注 前端南玖 第一時間獲取最新的文章~
掃描下方二維條碼關注公眾號,回覆進群,拉你進前端學習交流群