Nest.js系列之Providers及模塊功能使用詳解
提供者
Providers
是Nest
的一個基本概念。提供者是一個大的分類,比如sevice
、repository
、factory
、helper
等都是提供者。可以通過constructor
注入依賴關系。對象之間可以創(chuàng)建各種關系。提供者只是一個用@Injectable()
裝飾的類
在控制器的文章中,知道了如何創(chuàng)建一個簡單的控制器,控制器中不應該包含過多的復雜任務處理邏輯,這部分的任務邏輯處理應該交給Providers
因為Nest可以面向對象的方式設計和組織依賴性,所以強烈建議遵循SOLID原則
什么是SOLID原則
SOLID 原則其實是用來指導軟件設計的,它一共分為五條設計原則,分別是:
- 單一職責原則(SRP)
- 開閉原則(OCP)
- 里氏替換原則(LSP)
- 接口隔離原則(ISP)
- 依賴倒置原則(DIP)
服務
從創(chuàng)建一個簡單的服務開始,服務由控制器使用,服務其實也是一個提供者
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; } }
之前文章提到過可以使用命令快速創(chuàng)建一個服務 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(); } }
通過實例可以看出,控制器如果想要使用服務,只需要將服務通過依賴注入的方式注入到控制器中
constructor(private usersService: UsersService) {}
依賴注入
Nest 是建立在強大的設計模式,通常稱為依賴注入。我們建議在官方的 Angular文檔中閱讀有關此概念的精彩文章。
在 Nest
中,借助 TypeScript 功能,管理依賴項非常容易,因為它們僅按類型進行解析。在下面的示例中,Nest
將 catsService
通過創(chuàng)建并返回一個實例來解析 CatsService
(或者,在單例的正常情況下,如果現(xiàn)有實例已在其他地方請求,則返回現(xiàn)有實例)。解析此依賴關系并將其傳遞給控制器的構造函數(或分配給指定的屬性):
constructor(private readonly catsService: CatsService) {}
注冊提供者
現(xiàn)在我們已經定義了提供者(UsersService
),并且已經有了該服務的使用者(UsersController
),我們需要在 Nest
中注冊該服務,以便它可以執(zhí)行注入。 為此,我們可以編輯模塊文件(app.module.ts
),然后將服務添加到@Module()
裝飾器的 providers
數組中。
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 {}
小結
提供者可以簡單理解為是服務,但是畢竟服務只是一種提供者。在nest中通過使用服務來做邏輯處理。
模塊
什么是模塊
模塊是具有@Module()裝飾器的類,Nest使用模塊來組織代碼
每個nest程序至少有一個模塊,也就是根模塊。但是這是對于小應用來說的,對于大型程序來說,會擁有多個模塊,每個模塊擁有自己的功能。 @Module()裝飾器接受屬性對象
- providers 由nest注入器實例化的提供者,并且可以至少在整個模塊中共享
- controllers 必須創(chuàng)建的控制器
- imports 導入模塊的列表,這些模塊導出了此模塊中所需要的提供者
- exports 本模塊導出的可以用于其他模塊的提供者
默認情況下,該模塊封裝提供程序。這意味著無法注入既不是當前模塊的直接組成部分,也不是從導入的模塊導出的提供程序。因此,您可以將從模塊導出的提供程序視為模塊的公共接口或API。
功能模塊
通常來說,一個功能對應一個模塊,比如UsersController
和UsersService
應該屬于一個模塊,該模塊就稱為功能模塊
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命令來創(chuàng)建一個模塊
nest g module cats
當寫好一個功能模塊之后,要把模塊導入到根模塊
import {Module} from '@nestjs/common'; import {UsersModule} from './users/users.module'; @Module({ imports: [CatsModule], }) export class ApplocationModule {}
共享模塊
nest默認情況下,模塊是單例,因此可以很輕松的在多個模塊之間共享同一個提供者實例
其實在nest中,每個模塊都是共享模塊,可以被任意模塊重復使用。但是如果要在幾個模塊共享某一個服務,比如UsersService,那就需要在它所屬的模塊中導出這個服務,放到exports數組中
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 {}
每個導入UsersModule
的模塊都可以訪問UsersService
模塊的導出與導入
模塊不僅可以導出提供者,而且還可以導出自己導入的模塊
@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) {} }
全局模塊
有時候需要在任何地方導入相同的模塊,如果每個模塊都導入,就會很繁瑣,所以就有了全局模塊
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
裝飾器使模塊成為全局作用域。 全局模塊應該只注冊一次,最好由根或核心模塊注冊。 在上面的例子中,CatsService
組件將無處不在,而想要使用 CatsService
的模塊則不需要在 imports
數組中導入 CatsModule
。
使一切全局化并不是一個好的解決方案。 全局模塊可用于減少必要模板文件的數量。 imports
數組仍然是使模塊 API 透明的最佳方式。
動態(tài)模塊
Nest
模塊系統(tǒng)包括一個稱為動態(tài)模塊的強大功能。此功能使您可以輕松創(chuàng)建可自定義的模塊,這些模塊可以動態(tài)注冊和配置提供程序。動態(tài)模塊在這里廣泛介紹。在本章中,我們將簡要概述以完成模塊介紹。
以下是一個動態(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
)返回動態(tài)模塊。
此模塊 Connection
默認情況下(在 @Module()
裝飾器元數據中)定義提供程序,但此外-根據傳遞給方法的 entities
和 options
對象 forRoot()
-公開提供程序的集合,例如存儲庫。請注意,動態(tài)模塊返回的屬性擴展(而不是覆蓋)@Module()
裝飾器中定義的基本模塊元數據。這就是從模塊導出靜態(tài)聲明的 Connection
提供程序和動態(tài)生成的存儲庫提供程序的方式。
如果要在全局范圍內注冊動態(tài)模塊,請將 global
屬性設置為 true
。
{ global: true, module: DatabaseModule, providers: providers, exports: providers, }Copy to clipboardErrorCopied
如上所述,將所有內容全局化不是一個好的設計決策。
所述 DatabaseModule
可以被導入,并且被配置以下列方式:
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
如果要依次重新導出動態(tài)模塊,則可以 forRoot()
在導出數組中省略方法調用:
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 {}
總結
模塊就是一個功能的聚合,nest用模塊化來組織程序。
以上就是Nest.js系列之Providers及模塊功能使用詳解的詳細內容,更多關于Nest.js Providers模塊功能的資料請關注腳本之家其它相關文章!
相關文章
node.js程序作為服務并在windows下開機自啟動(用forever)
這篇文章主要介紹了node.js程序作為服務并在windows下開機自啟動的相關資料,因為實現(xiàn)的功能比較簡單,沒有選擇功能比較強大的pm2,文中選擇利用了forever,需要的朋友可以參考借鑒,下面來一起看看吧。2017-03-03nodemailer郵箱發(fā)送驗證碼的實現(xiàn)
郵箱注冊是常見的功能,通常需要發(fā)送郵箱驗證碼驗證,本文就來介紹一下nodemailer郵箱發(fā)送驗證碼的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2023-10-10mongoose設置unique不生效問題的解決及如何移除unique的限制
這篇文章主要給大家介紹了關于mongoose數據庫設置unique不生效問題的解決方法,以及Mongoose如何移除unique限制的方法示例,文中通過示例代碼介紹的非常詳細,需要的朋友們可以參考借鑒,下面隨著小編來一起學習學習吧。2017-11-11React和Node.js快速上傳進度條功能實現(xiàn)
這篇文章主要為大家介紹了React和Node.js快速上傳進度條功能實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03Node.js在child_process域和錯誤冒泡及捕獲實踐
這篇文章主要為大家介紹了Node.js在child_process域和錯誤冒泡及捕獲實踐示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11在windows上用nodejs搭建靜態(tài)文件服務器的簡單方法
這篇文章主要介紹了在windows上用nodejs搭建靜態(tài)文件服務器的簡單方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-08-08