Custom Rules

Custom Rules can be created by implementing IRule<T> interface.
ValidationResult determines the success of a Rule.
In order to keep Rules stateless, ValidationResult contains a list of arguments, which can be used in combination with the RuleKind to create error messages for failed rules.

RuleKind is a string that can be used to group very similar Rules. E.g. ValidateHotmailEmailAddress and ValidateGmailEmailAddress could return the same RuleKind, which could later on translate to 'invalid email address' for either rule failure.

    class Program
    {
        public class Member
        {
            public string Name { get; set; }
            public string Email { get; set; }
        }

        public class EmailRule : IRule<string>
        {
            public ValidationResult Validate(string value)
            {
                if (value == null 
                    || System.Text.RegularExpressions.Regex.IsMatch(value
                        , @"^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$"
                        , System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                {
                    return ValidationResult.Success;
                }
                else
                {
                    return ValidationResult.Fail(value);
                }
            }

            public string RuleKind
            {
                get { return this.GetType().Name; }
            }
        }


        static void Main(string[] args)
        {
            Engine engine = new Engine();

            engine.For<Member>()
                .Setup(member => member.Name)
                    .MustNotBeNullOrEmpty()
                .Setup(member => member.Email)
                    .MustNotBeNullOrEmpty()
                    .MustPassRule(new EmailRule());

            var member1 = new Member { Name = "athoma13", Email = "athoma13@codeplex.com" };
            var member2 = new Member { Name = "Blinky Bill", Email = "blinky&bush.co" };

            //Member1 is valid.
            bool isValidMember1 = engine.Validate(member1);

            //Member2 is not valid (email address rule failed)
            bool isValidMember2 = engine.Validate(member2);

        }
    }

Last edited Sep 6, 2011 at 11:09 AM by athoma13, version 1

Comments

PRoe Feb 28, 2013 at 8:11 PM 
I tend to implement all of these with an extension that looks like this:

public static M MustPassEmailRule<M, T>(this IMustPassRule<M, T, string> mpr)
{
return mpr.MustPassRule(new EmailRule());
}

.Setup(member => member.Email)
.MustNotBeNullOrEmpty()
.MustPassEmailRule()

MickeyPerlstein Feb 27, 2013 at 1:34 PM 
.MustPassRule(new EmailRule());

this is awqward, i'd say best practice would be to wrap this up nicely in an extension function.
this looks nice and clean.