簡體   English   中英

NestJs中,如何根據接口注入服務?

[英]In NestJs, how to inject a service based on its interface?

我有下一個模塊:payment.module.ts

@Module({
  controllers: [PaymentController],
})
export class PaymentModule {}

在下一個服務中,我想訪問基於接口的服務

支付服務.ts

export class PaymentService {
   constructor(private readonly notificationService: NotificationInterface,
}

通知.interface.ts

export interface NotificationInterface {
  // some method definitions
}

通知.service.ts

@Injectable()
export class NotificationService implements NotificationInterface {
  // some implemented methods
}

問題是如何基於NotificationInterface NotificationService

這是我找到的解決方案......使用接口作為值類型是不可能的,因為它們只存在於開發過程中。 轉譯接口后不再存在導致空對象值。 盡管使用字符串鍵作為提供值和注入裝飾器,但您的問題有一個解決方案:

支付模塊.ts

@Module({
  providers: [
    {
      provide: 'NotificationInterface',
      useClass: NotificationService
    }
  ]
})
export class PaymentModule {}

支付服務.ts

export class PaymentService {
   constructor(@Inject('NotificationInterface') private readonly notificationService: NotificationInterface,
}

正如 Gabriel 所提到的,您不能使用接口,因為它們在運行時不存在,但您可以使用抽象 class 它們在運行時可用,因此它們可以用作您的依賴注入令牌。

在 Typescript、class 聲明中也創建類型,所以你也可以實現它們,你不必擴展它們。

按照您的示例,您可以執行以下操作:

通知.interface.ts

export abstract class NotificationInterface {
  abstract send(): Promise<void>;
  // ... other method definitions
}

通知.service.ts

export class NotificationService implements NotificationInterface {
  async send() {...}
} 

然后在你的模塊中,像這樣提供它:

import NotificationInterface from "..."
import NotificationService from "..."

@Module({
  providers: [
    {
      provide: NotificationInterface,
      useClass: NotificationService
    }
  ]
})
export class PaymentModule {}

最后,通過 payments.service.ts 中的接口使用注入的服務

export class PaymentService {
   constructor(private readonly notificationService: NotificationInterface) {}
}

現在您不需要提供任何與您的 class 實現(並且只是一個 DI 構造)有些“無關”的自定義標記(如字符串或符號),但您可以使用 OOP model 中的結構。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM