关于实体验证,是早期在博客园看到一个同学的文章,里面利用扩展方法对实体进行验证的思路比较有创意。大家可以先跳过去先看一下:http://www.cnblogs.com/tristanguo/archive/2009/05/15/1457197.html
这个实体验证的扩展方法,设计比较巧妙,充分利用了链式编程的特点,让代码更加简洁和美观,唯一不足的地方是后来作者在改进的时候感觉不是很到位。于是偶的同事Rex同学,对这实体验证的扩展方法进行了改进,在我看来,应该算是比较完美的解决方法了,因此在我们的实际项目中,也比较大量的应用到了此扩展方法。在这里贴出来,给大家分享一下。
贴代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | 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语句块,取而代之的代码,示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 | 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组合语句,简洁、明了多了,并且还可以提高代码阅读的效率,强烈推荐各位同学使用。