您好,登錄后才能下訂單哦!
這篇文章主要介紹“Nest.js系列之Providers及模塊功能怎么使用”的相關(guān)知識(shí),小編通過(guò)實(shí)際案例向大家展示操作過(guò)程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“Nest.js系列之Providers及模塊功能怎么使用”文章能幫助大家解決問(wèn)題。
Providers
是Nest
的一個(gè)基本概念。提供者是一個(gè)大的分類(lèi),比如sevice
、repository
、factory
、helper
等都是提供者??梢酝ㄟ^(guò)constructor
注入依賴(lài)關(guān)系。對(duì)象之間可以創(chuàng)建各種關(guān)系。提供者只是一個(gè)用@Injectable()
裝飾的類(lèi)
在控制器的文章中,知道了如何創(chuàng)建一個(gè)簡(jiǎn)單的控制器,控制器中不應(yīng)該包含過(guò)多的復(fù)雜任務(wù)處理邏輯,這部分的任務(wù)邏輯處理應(yīng)該交給Providers
因?yàn)镹est可以面向?qū)ο蟮姆绞皆O(shè)計(jì)和組織依賴(lài)性,所以強(qiáng)烈建議遵循SOLID原則
SOLID 原則其實(shí)是用來(lái)指導(dǎo)軟件設(shè)計(jì)的,它一共分為五條設(shè)計(jì)原則,分別是:
單一職責(zé)原則(SRP)
開(kāi)閉原則(OCP)
里氏替換原則(LSP)
接口隔離原則(ISP)
依賴(lài)倒置原則(DIP)
從創(chuàng)建一個(gè)簡(jiǎn)單的服務(wù)開(kāi)始,服務(wù)由控制器使用,服務(wù)其實(shí)也是一個(gè)提供者
import { Injectable } from '@nestjs/common'; import { User } from './interfaces/user.interface'; @Injectable() export class UsersService { private readonly users: User[] = []; create(user: User) { this.users.push(user); } findAll(): User[] { return this.users; } }
之前文章提到過(guò)可以使用命令快速創(chuàng)建一個(gè)服務(wù) nest g service users
import { Controller, Get, Post, Body } from '@nestjs/common'; import { CreateUserDto } from './dto/create-user.dto'; import { UsersService } from './users.service'; import { User } from './interfaces/user.interface'; @Controller('users') export class CatsController { constructor(private usersService: UsersService) {} @Post() async create(@Body() createUserDto: CreateUserDto) { this.usersService.create(createUserDto); } @Get() async findAll(): Promise<User[]> { return this.usersService.findAll(); } }
通過(guò)實(shí)例可以看出,控制器如果想要使用服務(wù),只需要將服務(wù)通過(guò)依賴(lài)注入的方式注入到控制器中
constructor(private usersService: UsersService) {}
Nest 是建立在強(qiáng)大的設(shè)計(jì)模式,通常稱(chēng)為依賴(lài)注入。我們建議在官方的 Angular文檔中閱讀有關(guān)此概念的精彩文章。
在 Nest
中,借助 TypeScript 功能,管理依賴(lài)項(xiàng)非常容易,因?yàn)樗鼈儍H按類(lèi)型進(jìn)行解析。在下面的示例中,Nest
將 catsService
通過(guò)創(chuàng)建并返回一個(gè)實(shí)例來(lái)解析 CatsService
(或者,在單例的正常情況下,如果現(xiàn)有實(shí)例已在其他地方請(qǐng)求,則返回現(xiàn)有實(shí)例)。解析此依賴(lài)關(guān)系并將其傳遞給控制器的構(gòu)造函數(shù)(或分配給指定的屬性):
constructor(private readonly catsService: CatsService) {}
現(xiàn)在我們已經(jīng)定義了提供者(UsersService
),并且已經(jīng)有了該服務(wù)的使用者(UsersController
),我們需要在 Nest
中注冊(cè)該服務(wù),以便它可以執(zhí)行注入。 為此,我們可以編輯模塊文件(app.module.ts
),然后將服務(wù)添加到@Module()
裝飾器的 providers
數(shù)組中。
import { Module } from '@nestjs/common'; import { UsersController } from './users/users.controller'; import { UsersService } from './users/users.service'; @Module({ controllers: [UsersController], providers: [UsersService], }) export class AppModule {}
提供者可以簡(jiǎn)單理解為是服務(wù),但是畢竟服務(wù)只是一種提供者。在nest中通過(guò)使用服務(wù)來(lái)做邏輯處理。
模塊是具有@Module()裝飾器的類(lèi),Nest使用模塊來(lái)組織代碼
每個(gè)nest程序至少有一個(gè)模塊,也就是根模塊。但是這是對(duì)于小應(yīng)用來(lái)說(shuō)的,對(duì)于大型程序來(lái)說(shuō),會(huì)擁有多個(gè)模塊,每個(gè)模塊擁有自己的功能。 @Module()裝飾器接受屬性對(duì)象
providers 由nest注入器實(shí)例化的提供者,并且可以至少在整個(gè)模塊中共享
controllers 必須創(chuàng)建的控制器
imports 導(dǎo)入模塊的列表,這些模塊導(dǎo)出了此模塊中所需要的提供者
exports 本模塊導(dǎo)出的可以用于其他模塊的提供者
默認(rèn)情況下,該模塊封裝提供程序。這意味著無(wú)法注入既不是當(dāng)前模塊的直接組成部分,也不是從導(dǎo)入的模塊導(dǎo)出的提供程序。因此,您可以將從模塊導(dǎo)出的提供程序視為模塊的公共接口或API。
通常來(lái)說(shuō),一個(gè)功能對(duì)應(yīng)一個(gè)模塊,比如UsersController
和UsersService
應(yīng)該屬于一個(gè)模塊,該模塊就稱(chēng)為功能模塊
users/users.module.ts
import { Module } from '@nestjs/common'; import { UsersController } from './users.controller'; import { UsersService } from './users.service'; @Module({ controllers: [UsersController], providers: [UsersService], }) export class UsersModule {}
可以使用cli命令來(lái)創(chuàng)建一個(gè)模塊
nest g module cats
當(dāng)寫(xiě)好一個(gè)功能模塊之后,要把模塊導(dǎo)入到根模塊
import {Module} from '@nestjs/common'; import {UsersModule} from './users/users.module'; @Module({ imports: [CatsModule], }) export class ApplocationModule {}
nest默認(rèn)情況下,模塊是單例,因此可以很輕松的在多個(gè)模塊之間共享同一個(gè)提供者實(shí)例
其實(shí)在nest中,每個(gè)模塊都是共享模塊,可以被任意模塊重復(fù)使用。但是如果要在幾個(gè)模塊共享某一個(gè)服務(wù),比如UsersService,那就需要在它所屬的模塊中導(dǎo)出這個(gè)服務(wù),放到exports數(shù)組中
import { Module } from '@nestjs/common'; import { UsersController } from './users.controller'; import { UsersService } from './users.service'; @Module({ controllers: [UsersController], providers: [UsersService], exports: [UsersService] }) export class UsersModule {}
每個(gè)導(dǎo)入UsersModule
的模塊都可以訪問(wèn)UsersService
模塊不僅可以導(dǎo)出提供者,而且還可以導(dǎo)出自己導(dǎo)入的模塊
@Module({ imports: [CommonModule], exports: [CommonModule], }) export class CoreModule {}
提供者也可以注入到模塊中
import { Module } from '@nestjs/common'; import { UsersController } from './cats.controller'; import { UsersService } from './cats.service'; @Module({ controllers: [CatsController], providers: [CatsService], }) export class CatsModule { constructor(private readonly catsService: CatsService) {} }
有時(shí)候需要在任何地方導(dǎo)入相同的模塊,如果每個(gè)模塊都導(dǎo)入,就會(huì)很繁瑣,所以就有了全局模塊
import { Module, Global } from '@nestjs/common'; import { UsersController } from './users.controller'; import { UsersService } from './users.service'; @Global() @Module({ controllers: [UsersController], providers: [UsersService], exports: [UsersService], }) export class UsersModule {}
@Global
裝飾器使模塊成為全局作用域。 全局模塊應(yīng)該只注冊(cè)一次,最好由根或核心模塊注冊(cè)。 在上面的例子中,CatsService
組件將無(wú)處不在,而想要使用 CatsService
的模塊則不需要在 imports
數(shù)組中導(dǎo)入 CatsModule
。
使一切全局化并不是一個(gè)好的解決方案。 全局模塊可用于減少必要模板文件的數(shù)量。 imports
數(shù)組仍然是使模塊 API 透明的最佳方式。
Nest
模塊系統(tǒng)包括一個(gè)稱(chēng)為動(dòng)態(tài)模塊的強(qiáng)大功能。此功能使您可以輕松創(chuàng)建可自定義的模塊,這些模塊可以動(dòng)態(tài)注冊(cè)和配置提供程序。動(dòng)態(tài)模塊在這里廣泛介紹。在本章中,我們將簡(jiǎn)要概述以完成模塊介紹。
以下是一個(gè)動(dòng)態(tài)模塊定義的示例 DatabaseModule
:
import { Module, DynamicModule } from '@nestjs/common'; import { createDatabaseProviders } from './database.providers'; import { Connection } from './connection.provider'; @Module({ providers: [Connection], }) export class DatabaseModule { static forRoot(entities = [], options?): DynamicModule { const providers = createDatabaseProviders(options, entities); return { module: DatabaseModule, providers: providers, exports: providers, }; } }Copy to clipboardErrorCopied
forRoot()
可以同步或異步(Promise
)返回動(dòng)態(tài)模塊。
此模塊 Connection
默認(rèn)情況下(在 @Module()
裝飾器元數(shù)據(jù)中)定義提供程序,但此外-根據(jù)傳遞給方法的 entities
和 options
對(duì)象 forRoot()
-公開(kāi)提供程序的集合,例如存儲(chǔ)庫(kù)。請(qǐng)注意,動(dòng)態(tài)模塊返回的屬性擴(kuò)展(而不是覆蓋)@Module()
裝飾器中定義的基本模塊元數(shù)據(jù)。這就是從模塊導(dǎo)出靜態(tài)聲明的 Connection
提供程序和動(dòng)態(tài)生成的存儲(chǔ)庫(kù)提供程序的方式。
如果要在全局范圍內(nèi)注冊(cè)動(dòng)態(tài)模塊,請(qǐng)將 global
屬性設(shè)置為 true
。
{ global: true, module: DatabaseModule, providers: providers, exports: providers, }Copy to clipboardErrorCopied
如上所述,將所有內(nèi)容全局化不是一個(gè)好的設(shè)計(jì)決策。
所述 DatabaseModule
可以被導(dǎo)入,并且被配置以下列方式:
import { Module } from '@nestjs/common'; import { DatabaseModule } from './database/database.module'; import { User } from './users/entities/user.entity'; @Module({ imports: [DatabaseModule.forRoot([User])], }) export class AppModule {}Copy to clipboardErrorCopied
如果要依次重新導(dǎo)出動(dòng)態(tài)模塊,則可以 forRoot()
在導(dǎo)出數(shù)組中省略方法調(diào)用:
import { Module } from '@nestjs/common'; import { DatabaseModule } from './database/database.module'; import { User } from './users/entities/user.entity'; @Module({ imports: [DatabaseModule.forRoot([User])], exports: [DatabaseModule], }) export class AppModule {}
關(guān)于“Nest.js系列之Providers及模塊功能怎么使用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。