我有以下C#代码。在这里,验证被保留在类之外,以满足开闭原则。这很好用。但面临的挑战是--验证不是通用的。它是特定于employee类(例如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;
}
}发布于 2012-02-27 05:42:14
挑战是让您的规则知道要验证哪种类型的属性。您可以通过实现一个提供了SLaks建议的接口,或者动态地请求它,或者提供一个具体的规则类,提供关于如何访问给定属性的更多信息,例如:
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);https://stackoverflow.com/questions/9460324
复制相似问题