FluentValidation即服务

The*_*Sky 3 .net c# fluentvalidation

我正在使用FluentValidation 2来验证某些实体.我想创建一个IValidationService我可以传递到其他服务,以允许他们执行验证.我想像这样揭露它:

public interface IValidationEngine
{
    IEnumerable<ValidationError> Validate<T>(T entity);
}
Run Code Online (Sandbox Code Playgroud)

哪个ValidationError类封装了我的验证错误.理想情况下,我不想在我的某个服务(例如OrderValidator)中公开特定的验证器.我希望验证服务能够构建/找到正确的验证器.FV是否内置了用于查找特定类型的验证器(以及内部缓存)的内容?或者,我是否必须走这IValidatorFactory条路线,然后将每个验证器连接到我的IoC容器?

The*_*Sky 8

我已经设法用这个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.
    }
}
Run Code Online (Sandbox Code Playgroud)