2012-02-27 3 views
0

다음 C# 코드가 있습니다. 여기서 검증은 Open-Closed Principle을 충족시키기 위해 클래스 외부에서 유지됩니다. 이것은 잘 작동합니다. 그러나 문제는 일반적인 검증이 아니라는 것입니다. 직원 클래스에만 해당됩니다 (예 : DateOfBirthRuleForEmployee). 모든 개체 (DateOfBirthRuleForAnyObject)에 대해 유효성 검사를 일반화하려면 어떻게합니까?유효성 검사 일반 만들기

참고 : < ==> 유형 - 독립

참고하십시오 일반 확인 : 나는 또한 NameLengthRuleForEmployee 검증 있습니다. 앞으로 새로운 유효성 검사가 이루어질 수도 있습니다.

편집

일반적인 방법 예 : 규칙 유효성을 검사 유형의 어떤 속성이 아는 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

NameLengthRuleForEmployee 유효성 검사도 있습니다. 앞으로 새로운 유효성 검사가 이루어질 수도 있습니다. – Lijo

+0

그리고 무엇? 너는 무엇을 요구하고 있니? '동적'? – SLaks

답변

4

시도 성공이다.

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; 
    } 
} 
: 당신은 예를 들어 SLaks 또는 동적으로 quessing에 의해, 또는 지정된 속성에 액세스하는 방법에 대한 좀 더 많은 정보 구체적인 규칙 클래스를 제공하여 제안 단지를 제공하는 인터페이스를 구현하여이를 제공 할 수 있습니다

이것은 다음과 같은 방법으로 사용할 수 있습니다 :

NameRule<Employee> employeeNameRule = new NameRule<Employee>(x => x.name); 
employeeManager.addRule(employeeNameRule); 
관련 문제