我如何通过一组规则验证对象,每个规则都有一个ID和必须返回的结果类型。
我想要一些像Func的集合,我会发送对象,同时从每个对象中获得单独的结果。是否有一些最佳实践?
答案 0 :(得分:2)
你的问题有点广泛,但我在这里快速提出一些建议:
public class ObjectValidator<T> where T : class
{
private List<Expression<Func<T, bool>>> m_rules = new List<Expression<Func<T, bool>>>();
private List<ValidationResult> m_results = new List<ValidationResult>();
public ObjectValidator<T> AddRule(Expression<Func<T, bool>> rule)
{
// Null check, blah blah
m_rules.Add(rule);
return this; // Allows for chaining multiple rules together.
}
public List<ValidationResult> Validate(T objectInstance)
{
foreach (var rule in m_rules)
{
var isValid = rule.Compile()(objectInstance);
var fieldExpression = rule.Body as BinaryExpression;
var fieldNameExpression = fieldExpression.Left as MemberExpression;
string fieldName = fieldNameExpression != null ? fieldNameExpression.Member.Name : "Object";
var result = new ValidationResult(isValid, fieldName);
m_results.Add(result);
}
return m_results;
}
}
这里我们有一个名为ObjectValidator
的泛型类,它有两个方法:AddRule()
,它允许你传入一个类型为Func<T, bool>
的表达式,它基本上是你的验证条件。我们在Expression
而不是普通Func
传递的唯一原因是我们可以捕获实际属性名称作为验证结果的一部分。
Validate
方法将接收您正在验证的对象的实例并针对它运行每个规则,将结果放在此类型的列表中:
public class ValidationResult
{
public ValidationResult()
{
ID = Guid.NewGuid();
}
public ValidationResult(bool isValid, string fieldName)
{
ID = Guid.NewGuid();
IsValid = isValid;
FieldName = fieldName;
}
public Guid ID { get; private set; }
public bool IsValid { get; set; }
public string FieldName { get; set; }
}
然后最后使用它,让我们说我们有一个名为Test
的对象我们想要验证,看起来像这样:
public class Test
{
public int Property1 { get; set; }
public string Property2 { get; set; }
}
然后你可以使用这样的验证器:
Test instance = new Test { Property1 = 5, Property2 = "Bar" };
ObjectValidator<Test> validator = new ObjectValidator<Test>();
var results = validator.AddRule(x => x.Property1 < 10)
.AddRule(x => x.Property2 == "Foo")
.Validate(instance);
运行它以查看其外观:)您显然需要进行更改以符合您的要求,但这是让您入门的一些方法。