【问题标题】:C# FluentValidation for a hierarchy of classes用于类层次结构的 C# FluentValidation
【发布时间】:2015-06-09 11:38:47
【问题描述】:

我有一个数据类的层次结构

public class Base
{
    // Fields to be validated
}

public class Derived1 : Base
{
    // More fields to be validated
}

public class Derived2 : Base
{
    // More fields to be validated
}

在不复制基类字段规则的情况下,使用 FluentValidation 框架验证 Derived1 和 Derived2 的适当方法是什么?

【问题讨论】:

    标签: c# fluentvalidation


    【解决方案1】:
    public class Derived2Validator : AbstractValidator<Derived2>
    {
        public Derived2Validator()
        {
            Include(new BaseValidator());
            Include(new Derived1Validator());
            RuleFor(d => d.Derived1Name).NotNull();
        }
    }
    

    Derived2Validator 不需要继承BaseValidatorDerived1Validator

    使用Include 方法包含来自其他验证器的规则。

    【讨论】:

    • 我会采用这种方法,因为它有利于组合而不是继承,这是优秀开发人员的黄金法则
    • Include(new Derived2Validator()); 没必要吧?
    • 如果包含 Include(new Derived2Validator()); 将是一个无限循环;
    • 我发现 include 真的很有用,但有什么方法可以轻松测试它吗?我想到的唯一方法是为验证器做一个接口,在其中我调用一个包含方法来返回实例。
    【解决方案2】:

    一种方法如下:

    public class Base
    {
        public string BaseName { get; set; } 
    }
    
    public class Derived1 : Base
    {
        public string Derived1Name { get; set; }
    }
    
    public class BaseValidator<T> : AbstractValidator<T> where T : Base
    {
        public BaseValidator()
        {
            RuleFor(b => b.BaseName).NotNull();
        }
    }
    
    public class Derived1Validator : BaseValidator<Derived1>
    {
        public Derived1Validator()
        {
            RuleFor(d => d.Derived1Name).NotNull();
        }
    }
    

    因此,您首先创建基本验证器,使其接受泛型类型参数并指定泛型类型必须为base 类型。为您的基类设置一般规则并继续。

    对于任何验证您的基类的子类的验证器,您可以让这些验证器从 baseValidator 继承,其中 T 将是您的派生类类型。

    【讨论】:

    • 感谢您的回答!
    • 完美!奇迹般有效!请注意,无需在派生构造函数之后添加 : base() 。最初,我认为它不会在不显式调用基本构造函数的情况下获取基本测试。但确实如此!
    • 如果没有构造函数,则不需要添加 base(),因为它会自动存在。如果您有其他构造函数,除了默认的空,那么您必须使用 base() 使用您需要的签名。在验证类上.. 可能您永远不需要添加任何其他不同的构造函数。
    • 如果我现在有一个ICollection&lt;Base&gt; 并想要验证它怎么办?
    • 我注意到这种方法可以在服务器端进行验证,但是客户端的 data 属性不会通过 jquery 不显眼的验证来呈现,所以我不得不使用 Include方法。
    【解决方案3】:

    我尝试了 Include() 方法,但这并没有给我想要的结果,因为 .net 核心中 swagger 生成的模型没有显示任何变化。所做的工作是为具有基类的验证器创建一个新类来继承

    /// <summary>
    /// Base Class for entity validator classes that specifies a base validator class
    /// </summary>
    /// <typeparam name="T">The Type being validated</typeparam>
    /// <typeparam name="TBaseClass">The validater assigned to the base type of the type being validated</typeparam>
    public abstract class BaseAbstractValidator<T, TBaseClass> : AbstractValidator<T>
        where TBaseClass : IEnumerable<IValidationRule>
    {
        protected BaseAbstractValidator() => AppendRules<TBaseClass>();
    
        /// <summary>
        /// Add the set of validation rules
        /// </summary>
        /// <typeparam name="TValidationRule"></typeparam>
        private void AppendRules<TValidationRule>() where TValidationRule : IEnumerable<IValidationRule>
        {
            var rules = (IEnumerable<IValidationRule>)Activator.CreateInstance<TValidationRule>();
            foreach (var rule in rules)
            {
                AddRule(rule);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多