Search code examples
c#validationenterprise-libraryvalidation-application-bl

Apply Custom Validator by interface


Let's say I have an interface:

public interface ISomeInterface
{
    bool SomeBool { get; set; }

    string ValueIfSomeBool { get; set; }
}

And I have a number of classes that implement that. i.e.

public class ClassA : ISomeInterface
{
    #region Implementation of ISomeInterface

    public bool SomeBool { get; set; }

    public string ValueIfSomeBool { get; set; }

    #endregion

    [NotNullValidator]
    public string SomeOtherClassASpecificProp { get; set; }
}

And I have a Validation logic for the properties of this interface in a custom validator like so:

public class SomeInterfaceValidator : Validator<ISomeInterface>
{
    public SomeInterfaceValidator (string tag)
        : base(string.Empty, tag)
    {
    }

    protected override string DefaultMessageTemplate
    {
        get { throw new NotImplementedException(); }
    }

    protected override void DoValidate(ISomeInterface objectToValidate, object currentTarget, string key, ValidationResults validationResults)
    {
        if (objectToValidate.SomeBool && 
            string.IsNullOrEmpty(objectToValidate.ValIfSomeBool))
        {
            validationResults.AddResult(new ValidationResult("ValIfSomeBool cannot be null or empty when SomeBool is TRUE", currentTarget, key, string.Empty, null));
        }

        if (!objectToValidate.SomeBool && 
            !string.IsNullOrEmpty(objectToValidate.ValIfSomeBool))
        {
            validationResults.AddResult(new ValidationResult("ValIfSomeBool must be null when SomeBool is FALSE", currentTarget, key, string.Empty, null));
        }
    }
}

And I have an attribute for applying this validator that I decorate ISomeInterface with.

[AttributeUsage(AttributeTargets.Interface)]
internal class SomeInterfaceValidatorAttribute : ValidatorAttribute
{
    protected override Validator DoCreateValidator(Type targetType)
    {
        return new SomeInterfaceValidator(this.Tag);
    }
}

When I call Validation.Validate it doesn't seem to be firing the validation in SomeInterfaceValidator. It does the validation specific to ClassA but not that of the interface ISomeInterface.

How do I get this to work?

EDIT: I found one way to get this to work and that is to do SelfValidation, where I cast to ISomeInterface and validate like so. This will suffice, but still leaving the question open to see if there are any other ways to accomplish this.

    [SelfValidation]
    public void DoValidate(ValidationResults results)
    {
        results.AddAllResults(Validation.Validate((ISomeInterface)this));
    }

Solution

  • This is a limitation of the Validation Application Block. Here is an article that describes how to add Validator inheritance for VAB.