I have the following C# code. Here the validations are kept outside the class to satisfy Open – Closed Principle. This is working fine. But the challenge is – the validations are not generic. It is specific to employee class (E.g DateOfBirthRuleForEmployee). How do I make the validations generic for all objects (DateOfBirthRuleForAnyObject).
Note: Make Generic <==> Make Type-Independent
Note: I have NameLengthRuleForEmployee validation also. New validation may come in future.
EDIT
Generic Method Example: Using “OfType” in LINQ
CODE
class Program
{
static void Main(string[] args)
{
Employee employee = new Employee();
employee.DateOfBirth = DateTime.Now;
employee.Name = "Lijo";
DateOfBirthRuleForEmployee dobRule = new
DateOfBirthRuleForEmployee();
NameLengthRuleForEmployee nameRule = new
NameLengthRuleForEmployee();
EmployeeManager employeeManager = new EmployeeManager();
employeeManager.AddRules(dobRule);
employeeManager.AddRules(nameRule);
bool result = employeeManager.validateEntity(employee);
Console.WriteLine(result);
Console.ReadLine();
}
}
public interface IEntity
{
}
public interface IRule<TEntity>
{
bool IsValid(TEntity entity);
}
public class DateOfBirthRuleForEmployee : IRule<Employee>
{
public bool IsValid(Employee entity)
{
return (entity.DateOfBirth.Year <= 1975);
}
}
public class NameLengthRuleForEmployee : IRule<Employee>
{
public bool IsValid(Employee employee)
{
return (employee.Name.Length < 5);
}
}
public class Employee : IEntity
{
private DateTime dateOfBirth;
private string name;
public DateTime DateOfBirth
{
get
{
return dateOfBirth;
}
set
{
dateOfBirth = value;
}
}
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
}
public class EmployeeManager
{
RulesEngine<Employee> engine = new RulesEngine<Employee>();
public void AddRules(IRule<Employee> rule)
{
engine.AddRules(rule);
//engine.AddRules(new NameLengthRuleForEmployee());
}
public bool validateEntity(Employee employee)
{
List<IRule<Employee>> rulesList = engine.GetRulesList();
//No need for type checking. Overcame Invariance problem
bool status = true;
foreach (IRule<Employee> theRule in rulesList)
{
if (!theRule.IsValid(employee))
{
status = false;
break;
}
}
return status;
}
}
public class RulesEngine<TEntity> where TEntity : IEntity
{
private List<IRule<TEntity>> ruleList = new
List<IRule<TEntity>>();
public void AddRules(IRule<TEntity> rule)
{
//invariance is the key term
ruleList.Add(rule);
}
public List<IRule<TEntity>> GetRulesList()
{
return ruleList;
}
}