用于验证的循环继承

时间:2010-12-23 21:48:14

标签: c# generics inheritance .net-4.0

我想构建一个对象模型,在我尝试保存对象时自动连接验证。我正在使用DataAnnotations进行验证,这一切都运行良好,但我认为我的继承受到了影响。我正在寻找一些有关更好地验证方法的指导。

因此,要构建验证,我有这个接口

public interface IValidatable
{
    bool IsValid { get; }
    ValidationResponse ValidationResults { get; }
    void Validate();
}

然后,我有一个基类,我的所有对象都继承自。我做了一个课,因为我想自动连接验证调用。问题是验证必须知道它正在验证的类的类型。所以我像这样使用泛型。

public class CoreObjectBase<T> : IValidatable where T : CoreObjectBase<T>  
{
    #region IValidatable Members

    public virtual bool IsValid
    {
        get
        {
            // First, check rules that always apply to this type
            var result = new Validator<T>().Validate((T)this);

            // return false if any violations occurred
            return !result.HasViolations;
        }
    }

    public virtual ValidationResponse ValidationResults
    {
        get
        {
            var result = new Validator<T>().Validate((T)this);
            return result;
        }
    }

    public virtual void Validate()
    {
        // First, check rules that always apply to this type
        var result = new Validator<T>().Validate((T)this);

        // throw error if any violations were detected
        if (result.HasViolations)
            throw new RulesException(result.Errors);
    }

    #endregion
}

所以,我有这个循环继承声明。我的课程看起来像这样:

public class MyClass : CoreObjectBase<MyClass>
{

}

但是当我有一个更复杂的模型时会出现问题。因为我只能从一个类继承,所以当我有一个继承有意义的情况时,我相信子类不会对它们的属性进行验证。

public class Parent : CoreObjectBase<Parent>
{
    //properties validated
}

public class Child : Parent
{
    //properties not validated?
}

我还没有真正测试过这些情况下的验证,但是我很确定当我调用Child.Validate()时,带有数据注释的子项中的任何内容都不会自动验证;由于继承的配置方式。有更好的方法吗?

修改

有关进一步说明,这是我的验证。这是使用System.ComponentModel.DataAnnotations

public sealed class Validator<T> where T : CoreObjectBase<T>
{
    public ValidationResponse Validate(T entity)
    {
        var validationResults = new List<ValidationResult>();
        var context = new ValidationContext(entity, null, null);
        var isValid = Validator.TryValidateObject(entity, context, validationResults);

        return new ValidationResponse(validationResults.ToArray());
    }
}

1 个答案:

答案 0 :(得分:1)

我不明白为什么要使用继承 - 您已经将验证委托给外部类(Validator<T>),因此您应该能够将验证过程与目标对象完全分开。 / p>