关于实体验证,是早期在博客园看到一个同学的文章,里面利用扩展方法对实体进行验证的思路比较有创意。大家可以先跳过去先看一下:http://www.cnblogs.com/tristanguo/archive/2009/05/15/1457197.html 这个实体验证的扩展方法,设计比较巧妙,充分利用了链式编程的特点,让代码更加简洁和美观,唯一不足的地方是后来作者在改进的时候感觉不是很到位。于是偶的同事Rex同学,对这实体验证的扩展方法进行了改进,在我看来,应该算是比较完美的解决方法了,因此在我们的实际项目中,也比较大量的应用到了此扩展方法。在这里贴出来,给大家分享一下。 贴代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CommonLib
{
public static class EntityValidator
{
public static ValidateResult Validate(this T target,
Predicate predicate,
string errorMessage)
{
var result = new ValidateResult(target);
if (!predicate(target))
{
result.Errors.Add(errorMessage);
}
return result;
}
public static ValidateResult Validate(this ValidateResult target,
Predicate predicate,
string errorMessage)
{
if (!predicate(target.Entity))
{
target.Errors.Add(errorMessage);
}
return target;
}
}
public class ValidateResult
{
internal List Errors { get; set; }
internal T Entity { get; private set; }
public bool HasErrors
{
get { return Errors.Count > 0; }
}
internal ValidateResult(T entity)
{
Errors = new List();
Entity = entity;
}
public string[] ErrorMessages { get { return Errors.ToArray(); } }
}
}
有了这个实体验证的方法,代码可以简洁多了,并且再也不用在业务逻辑判断中,写入复杂的if…else语句块,取而代之的代码,示例如下:
ValidateResult validateResult =
content.Validate(c => !string.IsNullOrEmpty(c.Name), "Name为空")
.Validate(c => c.MobilePhone.Length == 11 , "MobilePhone长度不正确")
.Validate(c => c.Age >= 10), "年龄不在规定范围")
.Validate(c => c.Height <= 200 && c.Height >= 180, "身高不符合标准");
if (validateResult.HasErrors)
{
log.Info("实体验证失败:");
validateResult.ErrorMessages.ForEach(p => log.Info(p));
return null;
}
怎么样?这样的链式编程的代码,比起一大串的if…else组合语句,简洁、明了多了,并且还可以提高代码阅读的效率,强烈推荐各位同学使用。