我想将配置字符串传递给Pipe,但也想注入服务。 NesJs文档描述了如何做到彼此独立但又不能相互独立的两者。请看以下示例:
pipe.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;
}
}
controller.ts
@Controller('transcode')
export class TranscodeController {
@Post()
async transcode (
@Body( new FileExistsPipe('input')) transcodeRequest: JobRequest) {
return await this.videoProducer.addJob(transcodeRequest);
}
基本上,我希望能够将属性名称传递给我的管道(例如'input'
),然后让管道在请求中查找属性的值(例如const path = value[this.filePath]
),然后然后查看该文件在数据库中是否存在。如果不是,则抛出Bad Request错误,否则继续。
我面临的问题是我需要NestJ来注入我的DataBaseService。对于当前示例,它不会,并且我的IDE给我一个错误,提示new FileExistsPipe('input')
仅传递了一个参数,但期望传递两个参数(例如DatabaseService)。
反正有实现这一目标的方法吗?
答案 0 :(得分:1)
编辑:我刚刚检查了您的仓库(很抱歉之前没有找到它)。您的DatabaseService
是undefined
中的FIleExistPipe
,因为您使用了AppController
中的管道。 AppController
将在解决DatabaseModule
之前解决。如果要在forwardRef()
中使用管道,则可以使用DatabaseService
将AppController
注入管道中。最好的做法是在功能模块中提供功能控制器。
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);
}
您可以使用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);
}
memoize
只是一个简单的函数,用于使用filePath
缓存创建的mixin-pipe。因此,对于每个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);
}