简体   繁体   English

如何使用类验证器将服务注入到 nestjs 中的验证器约束接口?

[英]How to inject service to validator constraint interface in nestjs using class-validator?

I'm trying to inject my users service into my validator constraint interface but it doesn't seem to work:我正在尝试将我的用户服务注入我的验证器约束界面,但它似乎不起作用:

import { ValidatorConstraintInterface, ValidatorConstraint, ValidationArguments, registerDecorator, ValidationOptions } from "class-validator";
import { UsersService } from './users.service';

@ValidatorConstraint({ async: true })
export class IsEmailAlreadyInUseConstraint implements ValidatorConstraintInterface {
    constructor(private usersService: UsersService) {
        console.log(this.usersService);
    }
    validate(email: any, args: ValidationArguments) {
        return this.usersService.findUserByEmail(email).then(user => {
             if (user) return false;
             return true;
        });
        return false;
    }

}

But, as usersService is logged null, I can't access its methods.但是,由于 usersService 被记录为空,我无法访问它的方法。

Any insight on this matter?对这个问题有什么见解吗?

For those who might be suffering from this issue:对于可能遇到此问题的人:

class-validator requires you to use service containers if you want to inject dependencies into your custom validator constraint classes.如果要将依赖项注入自定义验证器约束类,则 class-validator 要求您使用服务容器。 From: https://github.com/typestack/class-validator#using-service-container来自: 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);

So that we need to add the user container function into the global application level.这样我们就需要将用户容器功能添加到全局应用层。

1. Add the following code to your main.ts bootstrap function after app declaration: 1. 在 app 声明后将以下代码添加到您的 main.ts bootstrap 函数中:

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  useContainer(app.select(AppModule), { fallbackOnErrors: true });
...}

The {fallbackOnErrors: true} is required, because Nest throw Exception when DI doesn't have required class. {fallbackOnErrors: true} 是必需的,因为当 DI 没有必需的类时,Nest 会抛出异常。

2. Add Injectable() to your constraint: 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. Inject the constraint into your module as a provider and make sure that the service you intend to inject into your constraint are also available to a module level: 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 {
}

You'll need to update class-validator 's container to use the Nest application to allow for Dependency Injection everywhere.您需要更新class-validator的容器以使用 Nest 应用程序以允许随处进行依赖注入。 This GitHub Issue goes through how to do it and some struggles people have faced with it. 这个 GitHub 问题介绍了如何做到这一点以及人们面临的一些困难。

Quick fix without reading the link:无需阅读链接即可快速修复:

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);
  useContainer(app, { fallback: true });
  await app.listen(3000);
}
bootstrap();

When doing this, make sure you also register your validators as you normally would any nest @Injectable()执行此操作时,请确保您也像往常一样注册验证器@Injectable()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM