2012-02-27 2 views
0

У меня есть следующий код C#. Здесь валидации хранятся вне класса, чтобы удовлетворить принцип открытого доступа. Это работает нормально. Но проблема в том, что валидации не являются общими. Он специфичен для класса сотрудников (например, DateOfBirthRuleForEmployee). Как сделать валидации универсальными для всех объектов (DateOfBirthRuleForAnyObject).Выполнение валидации Generic

Примечание: Сделать Generic < ==> Make Type-Independent

Примечание: У меня есть подтверждение NameLengthRuleForEmployee также. Новая валидация может произойти в будущем.

EDIT

Общий метод Пример: Using “OfType” in LINQ

КОД

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; 
    } 
} 
+0

Похоже, вы хотите использовать интерфейс 'IWasBorn'. – SLaks

+0

У меня есть имяLengthRuleForEmployee валидация также. Новая валидация может произойти в будущем. – Lijo

+0

И поэтому что? Что вы просите? 'Dynamic'? – SLaks

ответ

4

Наша задача для ваших правил, чтобы узнать, какое свойство какого типа проверки. Вы можете либо предоставить это, реализующий интерфейс, который обеспечивает только, что, как было предложено SLaks или quessing его динамически или путем предоставления конкретного класса правил с немного больше информации о том, как получить доступ к данному свойству, например:

class NameRule<T> : IRule<T> 
{ 
    private Func<T, string> _nameAccessor; 

    public NameRule(Func<T, string> nameAccessor) 
    { 
     _nameAccessor = nameAccessor; 
    } 

    public bool IsValid(T instance) 
    { 
     return _nameAccessor(instance).Length > 10; 
    } 
} 

этот курс может использоваться следующим образом:

NameRule<Employee> employeeNameRule = new NameRule<Employee>(x => x.name); 
employeeManager.addRule(employeeNameRule);