NestJS中如何向FilesInterceptor注入ConfigService值?
解决NestJS中FilesInterceptor无法注入ConfigService的问题
你遇到的问题核心在于:装饰器的执行时机早于类实例的创建。直接在@UseInterceptors里初始化FilesInterceptor时,this并不指向控制器实例,自然无法访问this.configService。下面提供两种可行的解决方案:
方案一:使用拦截器工厂函数(推荐)
利用NestJS的依赖注入机制,通过useFactory动态创建拦截器,直接注入ConfigService:
import { Controller, Post, UseInterceptors, Param } from '@nestjs/common'; import { FilesInterceptor } from '@nestjs/platform-express'; import { ConfigService } from '@nestjs/config'; import { diskStorage } from 'multer'; import * as fs from 'fs'; @Controller('your-controller') export class YourController { constructor(private readonly configService: ConfigService) {} @Post('product/image/:brandNo') @UseInterceptors({ useFactory: (configService: ConfigService) => { return FilesInterceptor('files', 2, { storage: diskStorage({ destination: (req, file, cb) => { const brandNo = req.params.brandNo; const basePath = configService.get<string>('BASE_PATH_FILE'); const directory = `../${basePath}/${brandNo}/product/image`; if (!fs.existsSync(directory)) { fs.mkdirSync(directory, { recursive: true }); } cb(null, directory); }, filename: (req, file, callback) => { callback(null, file.originalname); }, }), }); }, inject: [ConfigService], // 指定要注入的依赖 }) async uploadProductImage(@Param('brandNo') brandNo: string) { // 处理上传逻辑 } }
方案二:自定义拦截器继承FilesInterceptor
创建一个可注入的自定义拦截器,在构造函数中注入ConfigService,再传入父类的配置:
// custom-files.interceptor.ts import { Injectable } from '@nestjs/common'; import { FilesInterceptor } from '@nestjs/platform-express'; import { ConfigService } from '@nestjs/config'; import { diskStorage } from 'multer'; import * as fs from 'fs'; @Injectable() export class CustomFilesInterceptor extends FilesInterceptor { constructor(private configService: ConfigService) { // 调用父类构造函数,传入配置 super('files', 2, { storage: diskStorage({ destination: (req, file, cb) => { const brandNo = req.params.brandNo; const basePath = configService.get<string>('BASE_PATH_FILE'); const directory = `../${basePath}/${brandNo}/product/image`; if (!fs.existsSync(directory)) { fs.mkdirSync(directory, { recursive: true }); } cb(null, directory); }, filename: (req, file, callback) => { callback(null, file.originalname); }, }), }); } }
然后在控制器中使用这个自定义拦截器:
import { Controller, Post, UseInterceptors, Param } from '@nestjs/common'; import { CustomFilesInterceptor } from './custom-files.interceptor'; @Controller('your-controller') export class YourController { @Post('product/image/:brandNo') @UseInterceptors(CustomFilesInterceptor) async uploadProductImage(@Param('brandNo') brandNo: string) { // 处理上传逻辑 } }
最后别忘了在对应模块的providers数组中添加CustomFilesInterceptor,确保Nest能正确注入依赖。
内容的提问来源于stack exchange,提问作者Hikaru Shindo
相关产品推荐
相关产品推荐

