Again thanks to Pluralsite video and the suggestion from Keith Brown of Pluralsite

After my last post Keith Brown had made the suggestion to:

“You might try factoring the test into a SPECIFICATION (google the specification pattern for more). Very simple refactoring but then you’ll be able to use your tests not just for validation, but also for selection and build-to-order objects. Glad you’re enjoying the library!”

Which I thought was a great suggestion, however I am not a real programmer… So I turned to Pluralsite to help me to become a real programmer. I am posting this but I am not sure of the validity of this yet.

Any constructive criticism is greatly appreciated.

I decided to try to re-factor my test into a specification pattern. Here is my attempt:

I first developed the Interface IValidation<TEntity>:

namespace BusinessRules
{
    public interface IValidation<TEntity>
    {
        bool IsSatisfiedBy(TEntity entity);
    }
}

I then created three concrete classes that implemented the above interface.

Those classes were the classes I thought would be my validation rules that needed to be checked which are:

using System;

namespace BusinessRules
{
    public class EmployeeNameIsValid : IValidation<Employee>
    {
        public bool IsSatisfiedBy(Employee employee)
        {
            if (employee != null)
            {
                if (!String.IsNullOrEmpty(employee.Name))
                {
                    return true;
                }
                return false;
            }
            return false;
        }
    }
}
namespace BusinessRules
{
    public class EmployeeIdIsValid : IValidation<Employee>
    {
        public bool IsSatisfiedBy(Employee employee)
        {
            if (employee != null)
            {
                if (employee.EmployeeID > 0)
                {
                    return true;
                }
                return false;
            }
            return false;
        }
    }
}
namespace BusinessRules
{
    public class EmployeeDepartmentIdIsValid : IValidation<Employee>
    {

        public bool IsSatisfiedBy(Employee employee)
        {
            if (employee != null)
            {
                if (employee.DepartmentID > 0)
                {
                    return true;
                }
                return false;
            }
            return false;
        }
    }
}

I then Thanks to Wikipedia discovered this explanation of the pattern.  http://en.wikipedia.org/wiki/Specification_pattern. So I used there example to develop a group of extension methods for testing the And, Or and Not validation chaining.

I created the chaining functionality by creating the And, Or and Not as an extension methods like this:

namespace BusinessRules
{
    public class AndValidation<TEntity> : IValidation<TEntity>
    {
        private IValidation<TEntity> _validation1;
        private IValidation<TEntity> _validation2;

        public AndValidation(IValidation<TEntity> v1, IValidation<TEntity> v2)
        {
             _validation1 = v1;
             _validation2 = v2;
        }

        public bool IsSatisfiedBy(TEntity entity)
        {
            return _validation1.IsSatisfiedBy(entity) && _validation2.IsSatisfiedBy(entity);
        }
    }
}
namespace BusinessRules
{
    public class OrValidation<TEntity> : IValidation<TEntity>
    {
        private IValidation<TEntity> _validation1;
        private IValidation<TEntity> _validation2;

        public OrValidation(IValidation<TEntity> v1, IValidation<TEntity> v2)
        {
            _validation1 = v1;
            _validation2 = v2;
        }

        public bool IsSatisfiedBy(TEntity entity)
        {
            return _validation1.IsSatisfiedBy(entity) || _validation2.IsSatisfiedBy(entity);
        }
    }
}
namespace BusinessRules
{
    public class NotValidation<TEntity> : IValidation<TEntity>
    {
        private IValidation<TEntity> _validation1;

        public NotValidation(IValidation<TEntity> v1)
        {
            _validation1 = v1;
        }

        public bool IsSatisfiedBy(TEntity entity)
        {
            return !_validation1.IsSatisfiedBy(entity);
        }
    }
}
namespace BusinessRules
{
    public static class ExtensionMethods
    {
        public static IValidation<TEntity> AndValidation<TEntity>(this IValidation<TEntity> v1, IValidation<TEntity> v2)
        {
            return new AndValidation<TEntity>(v1, v2);
        }

        public static IValidation<TEntity> OrValidation<TEntity>(this IValidation<TEntity> v1, IValidation<TEntity> v2)
        {
            return new OrValidation<TEntity>(v1, v2);
        }

        public static IValidation<TEntity> NotValidation<TEntity>(this IValidation<TEntity> v1)
        {
            return new NotValidation<TEntity>(v1);
        }
    }
}

From there is was trying to figure out how to put it all together to have the functionality of the previous post. I re-factored the program class that I originally developed to try to improve on that functionality like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BusinessRules
{
    class Program
    {
        public static void Main(string[] args)
        {
            string error = EmployeeRules();
            Console.WriteLine(error);
            Console.ReadKey();
        }

        private static string EmployeeRules()
        {

            var employeeIdIsValid = new EmployeeIdIsValid();
            var employeeDepartmentIdIsValid = new EmployeeDepartmentIdIsValid();
            var employeeNameIsValid = new EmployeeNameIsValid();

            var rules = new List<Rule<Employee>>()
                            {

                                new Rule<Employee>()
                                    {
                                        Test = employeeNameIsValid.IsSatisfiedBy,
                                        Message = "name cannot be empty"
                                    },

                                new Rule<Employee>()
                                    {
                                        Test = employeeIdIsValid.IsSatisfiedBy,
                                        Message = "must have an employeeID"
                                    },

                                new Rule<Employee>()
                                    {
                                        Test = employeeDepartmentIdIsValid.IsSatisfiedBy,
                                        Message = "must have an assigned department"
                                    }

                            };

            StringBuilder stringBuilder = new StringBuilder();
            foreach (var employee in Employee.GetEmployee())
            {
                if (employee != null)
                {
                    var test = employeeNameIsValid.AndValidation(employeeIdIsValid).AndValidation(employeeDepartmentIdIsValid);
                    var isValid = test.IsSatisfiedBy(employee);

                    if (!isValid)
                    {
                        var failedRules = rules.Where(r => r.Test(employee) == false);

                        string errorMessage =
                            failedRules.Aggregate(new StringBuilder(),
                                                  (sb, r) => sb.AppendLine(r.Message),
                                                  sb => sb.ToString());
                        return stringBuilder.ToString() + Environment.NewLine + String.Format("Error: {0} is Invalid \r\n Employee {1}: {2} ", employee.Name, employee.Name, errorMessage);
                    }
                }

                if (employee != null) stringBuilder.Append(String.Format("Employee: {0} Is Valid \r\n", employee.Name));
            }
            return stringBuilder.ToString();
        }

    }
}

Again I am not sure of the validation of this code being a true “specification pattern”.

I want to thank Keith Brown for the suggestion and Wikipedia for the great example of the code to help me try to find the way to being a good developer!!

4 Comments on “Again thanks to Pluralsite video and the suggestion from Keith Brown of Pluralsite

  1. I think the idea is that a specification can be used for more than just validation. I’m personally thinking of refactoring my own validation logic so that the core check is performed by a specification (ISpecification). Then I can have a generic validation class that adds a message when the specification fails (IValidator, which holds an ISpecification and a message). Something like that anyhow. I’ve not yet worked it out, but it’s something interesting to think about. Good luck!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: