NestJS 循環(huán)依賴

2023-09-08 14:39 更新

當(dāng)兩個(gè)類(lèi)互相依賴時(shí)就會(huì)出現(xiàn)循環(huán)依賴. 例如,當(dāng) A 類(lèi)需要 B 類(lèi),而 B 類(lèi)也需要 A 類(lèi)時(shí),就會(huì)產(chǎn)生循環(huán)依賴。Nest 允許在提供者( provider )和模塊( module )之間創(chuàng)建循環(huán)依賴關(guān)系.

建議盡可能避免循環(huán)依賴。但是有時(shí)候難以避免,Nest提供了兩個(gè)方法來(lái)解決這個(gè)問(wèn)題.本章中我們提供了兩種技術(shù),即正向引用(forward reference)和模塊引用(ModuleRef)來(lái)從注入容器中獲取一個(gè)提供者。

我們也討論了在模塊間處理循環(huán)依賴的問(wèn)題。

循環(huán)依賴也可以使用封裝桶文件/index.ts文件成組導(dǎo)入。桶(Barrel)文件應(yīng)該從模塊/類(lèi)中省略掉。例如,當(dāng)在同一個(gè)目錄下作為桶文件導(dǎo)入時(shí)不應(yīng)使用桶文件,例如,cats/cats.controller不應(yīng)該導(dǎo)入cat到cats/cats.service文件。更多內(nèi)容參見(jiàn)github issue

前向引用

前向引用允許 Nest 引用目前尚未被定義的引用。當(dāng)CatsService 和 CommonService 相互依賴時(shí),關(guān)系的雙方都需要使用 @Inject() 和 forwardRef() ,否則 Nest 不會(huì)實(shí)例化它們,因?yàn)樗谢驹獢?shù)據(jù)都不可用。讓我們看看下面的代碼片段:

cats.service.ts
@Injectable()
export class CatsService {
  constructor(
    @Inject(forwardRef(() => CommonService))
    private readonly commonService: CommonService,
  ) {}
}

forwardRef() 需要從 @nestjs/common 包中導(dǎo)入的。

這只是關(guān)系的一方面?,F(xiàn)在讓我們對(duì) CommonService 做同樣的事情:

common.service.ts
@Injectable()
export class CommonService {
  constructor(
    @Inject(forwardRef(() => CatsService))
    private readonly catsService: CatsService,
  ) {}
}

實(shí)例化的順序是不確定的。不能保證哪個(gè)構(gòu)造函數(shù)會(huì)被先調(diào)用。

可選的模塊引用(ModuleRef)類(lèi)

一個(gè)選擇是使用forwardRef()來(lái)重構(gòu)你的代碼,并使用ModuleRef類(lèi)來(lái)在循環(huán)引用關(guān)系一側(cè)獲取提供者。更多關(guān)于ModuleRef類(lèi)的內(nèi)容參考這里。

模塊前向引用

為了處理模塊( module )之間的循環(huán)依賴,必須在模塊關(guān)聯(lián)的兩個(gè)部分上使用相同的 forwardRef():

common.module.ts
@Module({
  imports: [forwardRef(() => CatsModule)],
})
export class CommonModule {}


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)