Для тех, кто может страдать от этой проблемы:
class-validator требует от вас использования сервисных контейнеров, если вы хотите внедрить зависимости в свои пользовательские классы ограничений валидатора. From: https://github.com/typestack/class-validator#using -service-container
import {useContainer, Validator} from "class-validator";
// do this somewhere in the global application level:
useContainer(Container);
Так что нам нужно добавить функцию пользовательского контейнера в глобальный уровень приложения.
1 , Добавьте следующий код в функцию main.ts bootstrap после объявления приложения:
async function bootstrap() {
const app = await NestFactory.create(AppModule);
useContainer(app.select(AppModule), { fallbackOnErrors: true });
...}
Требуется {fallbackOnErrors: true}, потому что Nest генерирует исключение, когда DI не имеет требуемого класса .
2. Добавьте Injectable () к вашему ограничению:
import {ValidatorConstraint, ValidatorConstraintInterface} from 'class-validator';
import {UsersService} from './user.service';
import {Injectable} from '@nestjs/common';
@ValidatorConstraint({ name: 'isUserAlreadyExist', async: true })
@Injectable() // this is needed in order to the class be injected into the module
export class IsUserAlreadyExist implements ValidatorConstraintInterface {
constructor(protected readonly usersService: UsersService) {}
async validate(text: string) {
const user = await this.usersService.findOne({
email: text
});
return !user;
}
}
3. Вставьте ограничение в свой модуль в качестве поставщика и убедитесь, что служба, которую вы намереваетесь внедрить в свое ограничение, также доступна для уровня модуля:
import {Module} from '@nestjs/common';
import { UsersController } from './user.controller';
import { UsersService } from './user.service';
import { IsUserAlreadyExist } from './user.validator';
@Module({
controllers: [UsersController],
providers: [IsUserAlreadyExist, UsersService],
imports: [],
exports: []
})
export class UserModule {
}