iT邦幫忙

2023 iThome 鐵人賽

DAY 3
0
自我挑戰組

初探後端世界-使用Node.js框架開發網頁系列 第 3

你需要知道的9個元件功能介紹 -2(Providers)

  • 分享至 

  • xImage
  •  

Provider

Providers算是Nest中的一個概念,許多classes都能被稱作是Provider,像services,repositories等.關鍵在於它要可以透過依賴注入(Dependency injection)進行管理.

services

@Injectable裝飾器代表這個類別是可以被Nest IoC進行管理的,也就是這個類別是能被注入的對象.

https://ithelp.ithome.com.tw/upload/images/20230918/20163253ES9AwJAT7Y.png

什麼是依賴注入

在Controller、Service等元件類別的constructor裡,添加參數並指定類別為該參數的型別,就能將對應的實例注入到該類別中使用

Provider分類

ㄧ、標準Provider(Standard Provider)

https://ithelp.ithome.com.tw/upload/images/20230918/20163253Tmg7fcKDgV.png

標準Provider的展開式會長這樣:
https://ithelp.ithome.com.tw/upload/images/20230918/20163253FwOFsmV6fv.png

解釋:
在Angular中,每個provider的基本架構可拆分如下:

  provide: 要提供注入的內容
  useXXXX: YYY

(依需求使用:useClass、useExisting、useValue、useFactory等)

參考資料:https://www.gss.com.tw/blog/angular-26-%E6%B7%B1%E5%85%A5-service-3
將AppService換成一個物件,該物件的provide就是要使用的token,useClass代表要建立AppService這個實例

二、自訂Provider(Custom Provider)

自訂Provider需採用展開式

  1. Class Provider
  2. Value Provider
  3. Factory Provider
  4. Alias Provider
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MessageModule } from './module/message/message.module';

@Module({
  imports: [MessageModule],//注入自訂的Module
  controllers: [AppController],
  //Class Provider
  providers: [
  {
    provide:AppService,
    useClass:AppService,
  },
  //Value Provider
  {
  provide:'Hotel',
  useValue:'快樂旅館'
  },
  //Factory Provider
  {
   provide:'Hotel_Message',
   inject:[AppService], //將token為AppService的Provider注入,給工廠函式使用
   useFactory:(appService:AppService)=> {
     const hello=appService.getHello();
     return `貴賓 ${hello}`
   },
  },
  //Alias Provider
  {
    provide:'ALIAS_APP_SERVICE',//幫已存在的Provider取的別名
    useExisting:AppService, //已存在的那個Provider
  }
]
})
export class AppModule {}

注意我有使用$nest g module module/message創建了MessageModule
https://ithelp.ithome.com.tw/upload/images/20230918/20163253qwpfbyD5zj.png

三、可選式Provider(Optional Provider)

遇到Provider沒有被提供,但又被注入的情況,會出現錯誤,因為找不到對應的Provider,只要在前面加上@Optional裝飾器,該Provider就變成可選式,能順利啟動.

    @Optional()@Inject('NO_EXIST') private readonly noExist:unknown, 
    ) {
     ......
    }

Controller程式碼:

import { Controller, Get,Inject, Optional } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService,
    //因為使用字串作為token,所以使用@Inject參數取得
    @Inject('Hotel') private readonly author:string,
    @Inject('Hotel_Message') private readonly hotel_message:string,
    @Inject('ALIAS_APP_SERVICE') private readonly aliasAppService:AppService,
    @Inject('Custom_Message') private readonly customHotel:string,
    //可選式Provider
    @Optional()@Inject('NO_EXIST') private readonly noExist:unknown, 
    ) {
      console.log(this.appService===this.aliasAppService);
      console.log('Hotel',this.author);
      console.log('Hotel_Message',this.hotel_message);
      console.log('Custom_Message',this.customHotel);
      console.log('No_Exist',this.noExist);
    }

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

最後執行結果:

https://ithelp.ithome.com.tw/upload/images/20230918/20163253vcFlUfEkq2.png

總結:


-app.service.ts :決定function為何,記得service要是可注入的(@Injectable)
-app.module.ts :module裡會有controller跟provider(service會在provider裡,如果要建立的Provider不是Service需要自訂)
-app.controller.ts :決定Http Method跟要執行的function(如果有其他function要使用,記得在constructor中使用依賴注入)
-main.ts :把app.moudlue.ts引入執行程式


上一篇
你需要知道的9個元件功能介紹 -1(Controllers)
下一篇
你需要知道的9個元件功能介紹 -3(Modules)
系列文
初探後端世界-使用Node.js框架開發網頁12
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言