我想将配置字符串传递给管道,但也想注入服务。NesJs 文档描述了如何独立而不是一起完成这两项工作。举个例子:
管道.ts
@Injectable()
export class FileExistsPipe implements PipeTransform {
constructor(private filePath: string, db: DatabaseService) { }
async transform(value: any, metadata: ArgumentMetadata) {
const path = value[this.filePath];
const doesExist = await this.db.file(path).exists()
if(!doesExist) throw new BadRequestException();
return value;
}
}
Run Code Online (Sandbox Code Playgroud)
控制器.ts
@Controller('transcode')
export class TranscodeController {
@Post()
async transcode (
@Body( new FileExistsPipe('input')) transcodeRequest: JobRequest) {
return await this.videoProducer.addJob(transcodeRequest);
}
Run Code Online (Sandbox Code Playgroud)
基本上,我希望能够将属性名称传递到我的管道(例如'input'),然后让管道查找请求中的属性值(例如const path = value[this.filePath]),然后查看该文件是否存在于数据库中。如果没有,则抛出 Bad Request 错误,否则继续。
我面临的问题是我需要 NestJs 来注入我的 DataBaseService。对于当前的示例,它不会,并且我的 IDE 给出一个错误,new FileExistsPipe('input')仅传递了一个参数,但需要两个参数(例如 DatabaseService)。
有办法实现这个目标吗?
编辑:我刚刚检查了你的存储库(很抱歉之前错过了)。你DatabaseService在undefined中FIleExistPipe因为你在 中使用管道AppController。AppController会在DatabaseModule解决之前得到解决。如果您要在 中使用管道,则可以在管道中forwardRef()注入。这里的好习惯是在功能模块中提供功能控制器。DatabaseServiceAppController
export const FileExistPipe: (filePath: string) => PipeTransform = memoize(
createFileExistPipe
);
function createFileExistPipe(filePath: string): Type<PipeTransform> {
class MixinFileExistPipe implements PipeTransform {
constructor(
// use forwardRef here
@Inject(forwardRef(() => DatabaseService)) private db: DatabaseService
) {
console.log(db);
}
async transform(value: ITranscodeRequest, metadata: ArgumentMetadata) {
console.log(filePath, this.db);
const doesExist = await this.db.checkFileExists(filePath);
if (!doesExist) throw new BadRequestException();
return value;
}
}
return mixin(MixinFileExistPipe);
}
Run Code Online (Sandbox Code Playgroud)
您可以通过 来实现这一点Mixin。您可以导出一个返回此类的工厂函数,而不是导出一个injectable类。
export const FileExistPipe: (filePath: string) => PipeTransform = memoize(createFileExistPipe);
function createFileExistPipe(filePath: string) {
class MixinFileExistPipe implements PipeTransform {
constructor(private db: DatabaseService) {}
...
}
return mixin(MixinFileExistPipe);
}
Run Code Online (Sandbox Code Playgroud)
memoize只是一个简单的函数,用于缓存创建的 mixin-pipe 与filePath. 因此,对于每个filePath,您只有该管道的一个版本。mixin是一个辅助函数,从中导入nestjs/common将包装该类MixinFileExistPipe并使 DI 容器可用(因此DatabaseService可以注入)。用法:
@Controller('transcode')
export class TranscodeController {
@Post()
async transcode (
// notice, there's no "new"
@Body(FileExistsPipe('input')) transcodeRequest: JobRequest) {
return await this.videoProducer.addJob(transcodeRequest);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2207 次 |
| 最近记录: |