3. Nest Provider
Providers
Providers 是?Nest?的一個(gè)基本概念。許多基本的?Nest?類可能被視為 provider -?service,repository,?factory,?helper?等等。 他們都可以通過?constructor?注入依賴關(guān)系。 這意味著對象可以彼此創(chuàng)建各種關(guān)系,并且“連接”對象實(shí)例的功能在很大程度上可以委托給?Nest運(yùn)行時(shí)系統(tǒng)。 Provider只是一個(gè)用?@Injectable()?裝飾器注釋的類。
在前面的章節(jié)中,我們已經(jīng)創(chuàng)建了一個(gè)簡單的控制器?CatsController???刂破鲬?yīng)處理?HTTP?請求并將更復(fù)雜的任務(wù)委托給?providers。Providers 是純粹的?JavaScript?類,在其類聲明之前帶有?@Injectable()裝飾器。
由于?Nest?可以以更多的面向?qū)ο蠓绞皆O(shè)計(jì)和組織依賴性,因此我們強(qiáng)烈建議遵循?SOLID?原則。
服務(wù)
讓我們從創(chuàng)建一個(gè)簡單的?CatsService?開始。該服務(wù)將負(fù)責(zé)數(shù)據(jù)存儲(chǔ)和檢索,由其使用?CatsController,因此它被定義為provider是一個(gè)很好的選擇。因此,我們用這個(gè)類來裝飾?@Injectable()。
cats.service.ts
import { Injectable } from '@nestjs/common'; import { Cat } from './interfaces/cat.interface';@Injectable() export class CatsService {private readonly cats: Cat[] = [];create(cat: Cat) {this.cats.push(cat);}findAll(): Cat[] {return this.cats;} }Copy to clipboardErrorCopied要使用?CLI?創(chuàng)建服務(wù)類,只需執(zhí)行?$ nest g service cats?命令。
我們的?CatsService?是具有一個(gè)屬性和兩個(gè)方法的基本類。唯一的新特點(diǎn)是它使用?@Injectable()?裝飾器。該?@Injectable()?附加有元數(shù)據(jù),因此?Nest?知道這個(gè)類是一個(gè)?Nest?provider。需要注意的是,上面有一個(gè)?Cat?接口??雌饋硐襁@樣:
export interface Cat {name: string;age: number;breed: string; }Copy to clipboardErrorCopied現(xiàn)在我們有一個(gè)服務(wù)類來檢索?cat?,讓我們在?CatsController?里使用它 :
cats.controller.ts
import { Controller, Get, Post, Body } from '@nestjs/common'; import { CreateCatDto } from './dto/create-cat.dto'; import { CatsService } from './cats.service'; import { Cat } from './interfaces/cat.interface';@Controller('cats') export class CatsController {constructor(private readonly catsService: CatsService) {}@Post()async create(@Body() createCatDto: CreateCatDto) {this.catsService.create(createCatDto);}@Get()async findAll(): Promise<Cat[]> {return this.catsService.findAll();} }Copy to clipboardErrorCopiedCatsService?是通過類構(gòu)造函數(shù)注入的。注意這里使用了私有的只讀語法。這意味著我們已經(jīng)在同一位置創(chuàng)建并初始化了?catsService?成員。
依賴注入
Nest 是建立在強(qiáng)大的設(shè)計(jì)模式, 通常稱為依賴注入。我們建議在官方的?Angular文檔中閱讀有關(guān)此概念的精彩文章。
在?Nest?中,借助?TypeScript?功能,管理依賴項(xiàng)非常容易,因?yàn)樗鼈儍H按類型進(jìn)行解析。在下面的示例中,Nest?將?catsService?通過創(chuàng)建并返回一個(gè)實(shí)例來解析?CatsService(或者,在單例的正常情況下,如果現(xiàn)有實(shí)例已在其他地方請求,則返回現(xiàn)有實(shí)例)。解析此依賴關(guān)系并將其傳遞給控制器的構(gòu)造函數(shù)(或分配給指定的屬性):
constructor(private readonly catsService: CatsService) {}Copy to clipboardErrorCopied作用域
Provider通常具有與應(yīng)用程序生命周期同步的生命周期(“作用域”)。在啟動(dòng)應(yīng)用程序時(shí),必須解析每個(gè)依賴項(xiàng),因此必須實(shí)例化每個(gè)提供程序。同樣,當(dāng)應(yīng)用程序關(guān)閉時(shí),每個(gè)provider都將被銷毀。但是,有一些方法可以該標(biāo)provider生命周期的請求范圍。您可以在此處詳細(xì)了解這些技術(shù)。
定制providers
Nest?有一個(gè)內(nèi)置的控制反轉(zhuǎn)("IoC")容器,可以解決providers之間的關(guān)系。 此功能是上述依賴注入功能的基礎(chǔ),但要比上面描述的要強(qiáng)大得多。@Injectable()?裝飾器只是冰山一角, 并不是定義 providers 的唯一方法。相反,您可以使用普通值、類、異步或同步工廠??纯催@里找到更多的例子。
可選的providers
有時(shí),您可能需要解決一些依賴項(xiàng)。例如,您的類可能依賴于一個(gè)配置對象,但如果沒有傳遞,則應(yīng)使用默認(rèn)值。在這種情況下,關(guān)聯(lián)變?yōu)榭蛇x的,provider 不會(huì)因?yàn)槿鄙倥渲脤?dǎo)致錯(cuò)誤。
要指示provider是可選的,請?jiān)?constructor?的參數(shù)中使用?@optional()?裝飾器。
import { Injectable, Optional, Inject } from '@nestjs/common';@Injectable() export class HttpService<T> {constructor(@Optional() @Inject('HTTP_OPTIONS') private readonly httpClient: T) {} }Copy to clipboardErrorCopied請注意,在上面的示例中,我們使用自定義 provider,這是我們包含?HTTP_OPTIONS自定義標(biāo)記的原因。前面的示例顯示了基于構(gòu)造函數(shù)的注入,通過構(gòu)造函數(shù)中的類指示依賴關(guān)系。在此處詳細(xì)了解自定義providers及其關(guān)聯(lián)的?token。
基于屬性的注入
我們目前使用的技術(shù)稱為基于構(gòu)造函數(shù)的注入,即通過構(gòu)造函數(shù)方法注入providers。在某些非常特殊的情況下,基于屬性的注入可能會(huì)有用。例如,如果頂級(jí)類依賴于一個(gè)或多個(gè) providers,那么通過從構(gòu)造函數(shù)中調(diào)用子類中的?super()?來傳遞它們就會(huì)非常煩人了。因此,為了避免出現(xiàn)這種情況,可以在屬性上使用?@inject()?裝飾器。
import { Injectable, Inject } from '@nestjs/common';@Injectable() export class HttpService<T> {@Inject('HTTP_OPTIONS')private readonly httpClient: T; }Copy to clipboardErrorCopied如果您的類沒有擴(kuò)展其他provider,你應(yīng)該總是使用基于構(gòu)造函數(shù)的注入。
注冊 provider
現(xiàn)在我們已經(jīng)定義了 provider(CatsService),并且已經(jīng)有了該服務(wù)的使用者(CatsController),我們需要在?Nest?中注冊該服務(wù),以便它可以執(zhí)行注入。 為此,我們可以編輯模塊文件(app.module.ts),然后將服務(wù)添加到@Module()裝飾器的?providers?數(shù)組中。
app.module.ts
import { Module } from '@nestjs/common'; import { CatsController } from './cats/cats.controller'; import { CatsService } from './cats/cats.service';@Module({controllers: [CatsController],providers: [CatsService], }) export class AppModule {}Copy to clipboardErrorCopied得益于此,Nest?現(xiàn)在將能夠解決?CatsController?類的依賴關(guān)系。這就是我們目前的目錄結(jié)構(gòu):
src ├── cats │ ├──dto │ │ └──create-cat.dto.ts │ ├── interfaces │ │ └──cat.interface.ts │ ├──cats.service.ts │ └──cats.controller.ts ├──app.module.ts └──main.ts總結(jié)
以上是生活随笔為你收集整理的3. Nest Provider的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2. Nest:Controller
- 下一篇: 4. Nest :module (Mod