FluentValidation 作为服务

发布于 2024-10-14 07:54:51 字数 462 浏览 4 评论 0原文

我正在使用 FluentValidation 2 来验证一些实体。我想创建一个 IValidationService ,我可以将其传递给其他服务以允许它们执行验证。我想像这样公开它:

public interface IValidationEngine
{
    IEnumerable<ValidationError> Validate<T>(T entity);
}

其中 ValidationError 是一个封装我的验证错误的类。理想情况下,我不想向我的一项服务公开特定的验证器(例如 OrderValidator)。我希望验证服务能够构建/找到正确的验证器。 FV 是否有内置的东西来定位特定类型的验证器(并且它内部缓存)?或者,我是否必须走 IValidatorFactory 路线,然后将每个验证器与我的 IoC 容器连接?

I'm using FluentValidation 2 for validating some entities. I'd like to create an IValidationService that I can pass into other services to allow them to perform validation. I'd like to expose it like this:

public interface IValidationEngine
{
    IEnumerable<ValidationError> Validate<T>(T entity);
}

Where ValidationError is a class that encapsulates my validation errors. Ideally, I'd like to not have to expose a specific validator to one of my services (such as OrderValidator). I'd like the validation service be capable of constructing/finding the correct validator. Does FV have anything built in for locating a validator for a specific type (and it internally caches)? Or, do I have to go the IValidatorFactory route and then wire each validator with my IoC container?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

╄→承喏 2024-10-21 07:54:51

我已经设法使用 IValidatorFactory 方法解决了这个问题。我正在使用 Ninject,因此需要更改下面的具体 IoC 详细信息。

public interface IValidationService
{
    IEnumerable<ValidationError> Validate<T>(T entity)
        where T : class;
}

public class FluentValidationService : IValidationService
{
    private readonly IValidatorFactory validatorFactory;

    public FluentValidationService(IValidatorFactory validatorFactory)
    {
        this.validatorFactory = validatorFactory;
    }

    public IEnumerable<ValidationError> Validate<T>(T entity)
        where T : class
    {
        var validator = this.validatorFactory.GetValidator<T>();
        var result = validator.Validate(entity);
        return result.Errors.Select(e => new ValidationError(e.PropertyName, e.ErrorMessage));
    }
}

// Then implement FV's IValidatorFactory:

public class NinjectValidatorFactory : ValidatorFactoryBase
{
    private readonly IKernel kernel;

    public NinjectValidatorFactory(IKernel kernel)
    {
        this.kernel = kernel;
    }

    public override IValidator CreateInstance(Type validatorType)
    {
        return kernel.TryGet(validatorType) as IValidator;
    }
}

// I then wire both of these in a Ninject Module:

public class ValidationModule : NinjectModule
{
    public override void Load()
    {
        this.Bind<IValidationService>().To<FluentValidationService>().InRequestScope(); // Specific to MVC.
        this.Bind<IValidatorFactory>().To<NinjectValidatorFactory>().InRequestScope();
    }
}

// Then I can use it inside a service:

public class FooService
{
    private readonly IValidationService validationService;

    public FooService(IValidationService validationService)
    {
        this.validationService = validationService;
    }

    public bool Add(Foo foo)
    {
        if(this.validationService.Validate(foo).Any())
        {
            // Handle validation errors..
        }

        // do other implementation details here.
    }
}

I've managed to solve this with the IValidatorFactory method. I'm using Ninject, so specific IoC details below would need to be changed.

public interface IValidationService
{
    IEnumerable<ValidationError> Validate<T>(T entity)
        where T : class;
}

public class FluentValidationService : IValidationService
{
    private readonly IValidatorFactory validatorFactory;

    public FluentValidationService(IValidatorFactory validatorFactory)
    {
        this.validatorFactory = validatorFactory;
    }

    public IEnumerable<ValidationError> Validate<T>(T entity)
        where T : class
    {
        var validator = this.validatorFactory.GetValidator<T>();
        var result = validator.Validate(entity);
        return result.Errors.Select(e => new ValidationError(e.PropertyName, e.ErrorMessage));
    }
}

// Then implement FV's IValidatorFactory:

public class NinjectValidatorFactory : ValidatorFactoryBase
{
    private readonly IKernel kernel;

    public NinjectValidatorFactory(IKernel kernel)
    {
        this.kernel = kernel;
    }

    public override IValidator CreateInstance(Type validatorType)
    {
        return kernel.TryGet(validatorType) as IValidator;
    }
}

// I then wire both of these in a Ninject Module:

public class ValidationModule : NinjectModule
{
    public override void Load()
    {
        this.Bind<IValidationService>().To<FluentValidationService>().InRequestScope(); // Specific to MVC.
        this.Bind<IValidatorFactory>().To<NinjectValidatorFactory>().InRequestScope();
    }
}

// Then I can use it inside a service:

public class FooService
{
    private readonly IValidationService validationService;

    public FooService(IValidationService validationService)
    {
        this.validationService = validationService;
    }

    public bool Add(Foo foo)
    {
        if(this.validationService.Validate(foo).Any())
        {
            // Handle validation errors..
        }

        // do other implementation details here.
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文