NestJS控制器中如何在@UseInterceptors内访问注入的configService属性
问题原因
TypeScript装饰器的执行时机早于类实例化阶段,你在@UseInterceptors装饰器参数中使用this时,控制器实例还没有被创建,this并不指向控制器实例,自然无法访问到通过依赖注入生成的configService属性。
解决方案
给你两种常用的实现方案,按需选择即可:
方案1:模块级异步注册Multer配置(推荐)
如果你的上传配置在当前模块内通用,直接在对应模块中用MulterModule.registerAsync注入ConfigService生成配置,控制器内无需额外配置:
// UserModule 对应的模块文件 import { Module } from '@nestjs/common'; import { MulterModule } from '@nestjs/platform-express'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { diskStorage } from 'multer'; import { UserController } from './user.controller'; import { UserService } from './user.service'; @Module({ imports: [ MulterModule.registerAsync({ imports: [ConfigModule], useFactory: (configService: ConfigService) => ({ storage: diskStorage({ destination: configService.get('DEST_FORMATIONS'), // 其他storage相关配置 }), // 其他multer全局配置,比如文件大小限制、格式校验等 }), inject: [ConfigService], }), ], controllers: [UserController], providers: [UserService] }) export class UserModule {}
控制器中直接使用FileInterceptor即可,会自动读取模块注册的配置:
@UseInterceptors(FileInterceptor('file')) @Post('upload') upload(@UploadedFile() file) { // 你的业务逻辑 }
方案2:自定义可注入的拦截器(单路由特殊配置用)
如果只有单个路由需要用到这个动态配置,不想影响模块内其他上传接口,可以自定义一个可注入的拦截器:
// 先定义自定义拦截器 import { injectable, ExecutionContext, CallHandler, NestInterceptor } from '@nestjs/common'; import { FileInterceptor } from '@nestjs/platform-express'; import { diskStorage } from 'multer'; import { ConfigService } from '@nestjs/config'; @injectable() class CustomUploadInterceptor implements NestInterceptor { constructor(private configService: ConfigService) {} intercept(context: ExecutionContext, next: CallHandler) { const interceptor = new (FileInterceptor('file', { storage: diskStorage({ destination: this.configService.get('DEST_FORMATIONS'), // 其他自定义配置 }) }))(); return interceptor.intercept(context, next); } } // 控制器中直接使用即可 @UseInterceptors(CustomUploadInterceptor) @Post('upload') upload(@UploadedFile() file) { // 你的业务逻辑 }
内容的提问来源于stack exchange,提问作者Med
相关产品推荐
相关产品推荐

