NestJS中基于接口注入Provider失败的问题求助
看起来你遇到的问题有两个核心点:一是TypeScript接口在编译后会被擦除,不过你已经用字符串令牌'IStorageBase'做了替代,这部分思路是对的;真正触发错误的是你的BlobService构造函数需要BlobDependencies参数,但你没有在CoreModule中提供这个依赖项,Nest找不到这个Object(也就是BlobDependencies实例),所以抛出了依赖解析失败的报错。
下面是具体的解决步骤:
第一步:为BlobService的依赖提供配置值
你需要把BlobDependencies的具体配置(connectionString和containerName)作为provider注册到Nest容器中,这样它才能被注入到BlobService的构造函数里。开发环境可以直接硬编码,生产环境推荐从配置模块读取(比如@nestjs/config)。
修改core.module.ts,添加配置provider:
// core.module.ts import { Module } from '@nestjs/common'; import { BlobService } from './blob.service'; // 定义Azure Blob的配置项 const blobConfigProvider = { provide: 'BlobDependencies', useValue: { connectionString: '你的Azure存储连接字符串', containerName: '你的容器名称', }, }; const blobServiceProvider = { provide: 'IStorageBase', useClass: BlobService, }; @Module({ providers: [blobConfigProvider, blobServiceProvider], exports: [blobServiceProvider], }) export class CoreModule {}
第二步:修改BlobService构造函数,显式注入配置
在BlobService的构造函数上添加@Inject()装饰器,指定注入刚才定义的BlobDependencies令牌:
// blob.service.ts import { Injectable, Inject } from '@nestjs/common'; import { BlobServiceClient, ContainerClient } from '@azure/storage-blob'; import { IStorageBase } from './storage-base.interface'; type BlobDependencies = { connectionString: string; containerName: string; }; @Injectable() export class BlobService implements IStorageBase { private readonly blobServiceClient: BlobServiceClient; private readonly containerClient: ContainerClient; constructor(@Inject('BlobDependencies') blobDependencies: BlobDependencies) { // 这里可以正常初始化Azure Blob客户端了 this.blobServiceClient = BlobServiceClient.fromConnectionString(blobDependencies.connectionString); this.containerClient = this.blobServiceClient.getContainerClient(blobDependencies.containerName); } // 你的其他方法保持不变 upload(filename: string): Promise<string> { // 实现逻辑 return Promise.resolve('上传路径'); } deleteLocalFile(filename: string): Promise<void> { // 实现逻辑 return Promise.resolve(); } private getAbsolutePath(filename: string): string { // 实现逻辑 return ''; } }
(可选)用Symbol替代字符串令牌,避免命名冲突
为了防止字符串令牌可能出现的命名冲突,推荐用Symbol作为注入令牌,更安全规范:
首先在接口文件中定义Symbol:
// storage-base.interface.ts export const STORAGE_BASE_TOKEN = Symbol('IStorageBase'); export interface IStorageBase { upload(fileName: string): Promise<string>; deleteLocalFile(fileName: string): Promise<void>; }
然后更新CoreModule中的provider:
// core.module.ts import { STORAGE_BASE_TOKEN } from './storage-base.interface'; const blobServiceProvider = { provide: STORAGE_BASE_TOKEN, useClass: BlobService, };
最后在注入的地方使用这个Symbol:
// video-cut-out.service.ts import { Injectable, Inject } from '@nestjs/common'; import { STORAGE_BASE_TOKEN, IStorageBase } from '../core/storage-base.interface'; @Injectable() export class VideoCutOutService { constructor( @Inject(STORAGE_BASE_TOKEN) private readonly storageService: IStorageBase, ) {} // 业务逻辑中使用storageService }
现在CoreModule已经完整提供了BlobDependencies和BlobService的依赖,Nest可以正确解析所有注入项,启动应用就不会再出现依赖解析错误了。
内容的提问来源于stack exchange,提问作者maclo
相关产品推荐
相关产品推荐

