Providers算是Nest中的一個概念,許多classes都能被稱作是Provider,像services,repositories等.關鍵在於它要可以透過依賴注入(Dependency injection)進行管理.
@Injectable裝飾器代表這個類別是可以被Nest IoC進行管理的,也就是這個類別是能被注入的對象.
在Controller、Service等元件類別的constructor裡,添加參數並指定類別為該參數的型別,就能將對應的實例注入到該類別中使用
標準Provider的展開式會長這樣:
解釋:
在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需採用展開式
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
遇到Provider沒有被提供,但又被注入的情況,會出現錯誤,因為找不到對應的Provider,只要在前面加上@Optional裝飾器,該Provider就變成可選式,能順利啟動.
@Optional()@Inject('NO_EXIST') private readonly noExist:unknown,
) {
......
}
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();
}
}
-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引入執行程式