BusinessRules using LINQ

After watching the Pluralsite video on LINQ from Scott Allen. I wanted to implement a example that would help me understand some of the functionality that I saw. I was really impressed with the implementation of the Business Rules that Scott did with the LINQ aggregate function. So I developed a small console application that used some of this technology. I first developed a small Rules class like the video shows:

using System;

namespace BusinessRules
{
    public class Rule<T>
    {
        public Func<T, bool> Test { get; set; }
        public string Message { get; set; }
    }
}

This is a small generic class that exposes two properties. This first property is a Func<T, TResult> delegate. Which MSDN states a Func<T, TResult>: Encapsulates a method that has one parameter and returns a value of the type specified by the TResult parameter. And the second property is the message that will be used for the validation.

I then created a small employee class that will be my data to test in the validation rules.

This is very simple class like this:

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

namespace BusinessRules
{
    public class Employee
    {
        #region Properties

        public int EmployeeID { get; set; }
        public string Name { get; set; }
        public int DepartmentID { get; set; }

        #endregion

        #region Constructor
        public Employee()
        {
            //Used for AutoImplementation
        }

        public static List<Employee> GetEmployee()
        {
           var employee =  new List<Employee>
                                {
                                    new Employee() { EmployeeID = 1, Name = "Allan", DepartmentID = 1 },
                                    new Employee() { EmployeeID = 2, Name = "Quincy", DepartmentID = 2},
                                    new Employee() { EmployeeID = 3, Name = "Bella", DepartmentID = 2},
                                    new Employee() { EmployeeID = 0, Name = "Rylee", DepartmentID = 3}
                                }.ToList();

            return employee;

        }
        #endregion

        #region Methods()
        public override string ToString()
        {
            return string.Format("Employee: EmployeeID = {0}, Name = {1}, DepartmentID = {2}", EmployeeID, Name,
                                 DepartmentID);
        }
        #endregion

    }
}

Finally I created a small EmployeeRules() method that would be used to validate the business rules.

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 rules = new List<Rule<Employee>>()
                            {
                                new Rule<Employee>(){ Test = e => !String.IsNullOrEmpty(e.Name),
                                    Message = "name cannot be empty"},

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

                                new Rule<Employee>() {Test = e => e.EmployeeID > 0,
                                    Message = "must have an employeeID"}
                            };

            StringBuilder stringBuilder = new StringBuilder();
            foreach (var employee in Employee.GetEmployee())
            {
                if (employee != null)
                {
                    bool isValid = rules.All(r => r.Test(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);
                    }
                }

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

    }
}

This functionality seems to be very simple and straight forward to even me and I am not very smart. I was impressed by the simplicity that Scott Allen showed with his video and yet still showed the true power of LINQ in one example.

Thanks to Scott Allen and http://www.pluralsight-training.net for the examples and functionality.

One Comment on “BusinessRules using LINQ

  1. 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!

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: