NestJS開發(fā)核心概念Providers類基本用法詳解
前言
Providers
是Nest
中的一個基本概念,許多Nest
中定義的類都可以被視為一個Provider
,比如:service、repository、factory、helper等,它們都可以通過constructor
注入依賴關(guān)系,這就意味著類與類之間可以創(chuàng)建各種依賴關(guān)系,并且維護各個類之間依賴關(guān)系的工作將委托給Nest
運行時系統(tǒng)。
Provider類(service)基本用法
前面幾章我們通過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`; } }
使用步驟如下:
@Injectable()裝飾器
這里的NanjiuService
類通過@Injectable
裝飾器標(biāo)記為一個provider
,表明該類可以被Nest
的IOC
容器管理
在module中注冊
服務(wù)需要在對應(yīng)的module
中進行注冊,如果不注冊IOC
容器是不會幫你創(chuàng)建對象的,而且還會報錯
// nanjiu.module.ts @Module({ controllers: [NanjiuController], providers: [NanjiuService] }) export class NanjiuModule {}
在controller中注入并使用
在module
中注冊service
類后,再通過controller
的構(gòu)造函數(shù)進行注入,那么該類就可以在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); } }
可以看到是通過類構(gòu)造函數(shù) constructor(private readonly nanjiuService: NanjiuService) {}
這種方式來進行依賴注入的,Nest提供了IOC
容器利用Typescript自帶類型的特點自動創(chuàng)建對象的能力,注意這里是單例模式,如果該Service在其它地方也被用過,那么會在不會重新創(chuàng)建對象,各個應(yīng)用只會有一個該Service的對象,容器會先尋找當(dāng)前有沒有,如果沒有再進行創(chuàng)建。
自定義Provider
Provider
可以是一個值(value),也可以是一個類(class),還可以是一個工廠函數(shù)(factory)
useClass
上面providers
的那種寫法其實是一種簡寫,它的完整寫法應(yīng)該是這樣:
// nanjiu.module.ts @Module({ controllers: [NanjiuController], // 控制器 providers: [{ provide: 'NANJIU', // 自定義依賴注入的標(biāo)識 useClass: NanjiuService // 依賴注入的類 }] }) export class NanjiuModule {}
完整寫法可以通過provide
屬性給不同的provider
標(biāo)注不同的token
然后再controller
中需要使用@Inject(對應(yīng)的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
還可以使用useValue
自定義注入值
// nanjiu.module.ts @Module({ // 模塊裝飾器 controllers: [NanjiuController], // 控制器 providers: [{ provide: 'NANJIU', // 自定義依賴注入的標(biāo)識 useValue: { name: 'nanjiu' // 依賴注入的值 } }] })
useFactory
工廠函數(shù)可以提供動態(tài)的provider
,由factory
函數(shù)的返回值來確定,factory
函數(shù)可以很簡單也可以很復(fù)雜,它也可以使用其它provider
,不過需要在inject
屬性進行注入,注入的provider
可以是可選的
- 工廠函數(shù)可以接受(可選)參數(shù)。
- (可選)
inject
屬性接受一組提供程序,Nest 將在實例化過程中解析這些提供程序并將其作為參數(shù)傳遞給工廠函數(shù)。這兩個列表應(yīng)該是相關(guān)的:Nest 將以inject
相同的順序?qū)⒘斜碇械膶嵗鳛閰?shù)傳遞給工廠函數(shù)。
// 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', // 自定義依賴注入的標(biāo)識 useClass: NanjiuService // 依賴注入的類 }, UserService, { provide: 'USER', // 自定義依賴注入的標(biāo)識 useFactory: (...args) => { // 工廠模式 console.log('useFactory', args) return new UserService() // 依賴注入的類 }, inject: [UserService] // 依賴注入的類 } ] }) export class NanjiuModule {}
可選的Provider
有時你可能存在不一定需要解決的依賴關(guān)系。例如,你的類可能依賴于配置對象,但如果沒有傳遞任何內(nèi)容,則應(yīng)使用默認值。在這種情況下,依賴關(guān)系變得可選,這時候可以給對應(yīng)的注入服務(wù)再增加一個@Optional()
裝飾器就行
import { Injectable, Optional, Inject } from '@nestjs/common'; @Injectable() export class HttpService<T> { constructor(@Optional() @Inject('HTTP_OPTIONS') private httpClient: T) {} }
異步Provider
useFactory
可以返回一個promise 或者其他異步操作,Nest 將在實例化任何依賴(注入)此類提供程序的類之前等待promise
的結(jié)果。
// nanjiu.module.ts @Module({ // 模塊裝飾器 controllers: [NanjiuController], // 控制器 providers: [ UserService, { provide: 'USER', // 自定義依賴注入的標(biāo)識 useFactory: async () => { // 工廠模式 return new Promise((resolve, reject) => { setTimeout(() => { resolve(new UserService()) }, 1000) }) }, inject: [UserService] // 依賴注入的類 } ] }) export class NanjiuModule {}
以上就是NestJS開發(fā)核心概念Providers類基本用法詳解的詳細內(nèi)容,更多關(guān)于NestJS核心Providers類的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
關(guān)于npm install過程失敗的幾種處理方式
這篇文章主要介紹了關(guān)于npm install過程失敗的幾種處理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06