zoukankan      html  css  js  c++  java
  • CommonLibrary之Validation(2)

      上一篇,介绍了CommonLibrary的Validation验证模块的接口,类继承关系以及ValidatorFluent链式调用的实现,这里继续把例子从头看起,简单的,一看就明白的设计和实现就不做赘述了,说说我理解中的一些比较好的值得学习的观念或方法;首先看:

    Validation.IsAlpha("123abc", false)
    Validation.IsAlphaNumeric(
    "123abc", false, errors, "")
    Validation.AreEqual
    <T>(t1, t2);

      Validation,ValidationExtensions,ValidationExtensionsAssertive,3个类文件中同使用static partial class Validation,作者把基本验证(Validation)实现保存错误的参数类IErrors的ValidationExtensions,实现IComparable<T>,用来做类型比较的ValidationExtensionsAssertive物理上分开放置,这个可以在我们平时的设计做参考,物理上的好的放置让我们逻辑更清楚,维护更方便,其实无所谓了,看自己的理解和实际的编码需求了。这块很简单,看看就明白了。

      其实如果我们想在懒点,简单的验证我们可以用扩展方法实现,"123abc".IsNumericExp(),恩,一切都是现成的,还等什么呢?

     

     public static bool IsNumericExp(this string str) {
                return Regex.IsMatch(str, RegexPatterns.Numeric);
            }
    

      这里讲讲这个接口: IComparable<T>,定义由值类型或类实现的通用的比较方法,以为排序实例创建类型特定的比较方法,如果我们要使用Validation类中的的类型比较方法,那么首先得实现
    IComparable<>泛型接口的public int CompareTo(T t)方法,在该方法中编写我们需要比较的东西,比如:

     

    public class User:IComparable<User>
        {
            public string UserName { get; set; }
            public DateTime CreateDate { get; set; }
            public string Email { get; set; }
            public string MobilePhone { get; set; }
    
    
            #region IComparable<User> 成员
    
            public int CompareTo(User other)
            {
                return this.UserName.CompareTo(other.UserName);
            }
    
            #endregion
    }
    //调用方法:
    var errors = new ValidationResults();
    Validation.AreEqual<User>(user1, user2,errors,"");
    PrintErrors(errors);
    

       Lamda

     

     //实现
     public void Example3_Lamda()
            {
                var val = new Validator(valEvent =>
                {
                    int errCount = valEvent.Results.Count;
                    Validation.IsEmail("kishore@", false, valEvent.Results, string.Empty);
                    Validation.IsUrl("http://www", false, valEvent.Results, string.Empty);
                    Validation.IsPhoneUS("111-111-111", false, valEvent.Results, string.Empty);
    
                    return errCount == valEvent.Results.Count;
                });
                PrintErrors(val.Validate());
            }
    //其实很简单,看一下Validator的构造函数就清楚了,
    public Validator(Func<ValidationEvent, bool> validator)
            {
                _validatorLamda = validator;
            }
    

      这里其实就是通过传递泛型委托,ValidationEvent在这里起了什么用?看到这里我真的没想明白,其实只要Action< IValidationResults >就能实现的东西,作者为什么要写的这么复杂,仅仅为了参数传递白加上一个ValidationEvent?比如下面实现:

     

    Action<IValidationResults> _action;
            public Validator(Action<IValidationResults> action)
            {
                _action = action;
            }
            public IValidationResults TestAction()
            {
                _lastValidationResults = new ValidationResults();
                if (_action != null)
                {
                    _action(_lastValidationResults);
                }
                return _lastValidationResults;
            }
    
    
    var t = new Validator(errors =>
                {
                    Validation.IsEmail("kishore@", false, errors, "邮箱");
                    Validation.IsUrl("http://www", false, errors, "网址");
                    Validation.IsPhoneUS("111-111-111", false, errors, "电话");
                });
    t. TestAction();
    

      RulesList验证和Lamda验证的实现方式一样,就多了一个List< ValidationRuleDef >来保存Func < ValidationEvent ,bool>集合~!

    CustomValidator自定义验证

    public void Example6_Custom()
            {
                ComLib.IValidator validator = new MyCustomUserIdValidator("admin");
                IValidationResults errors = new ValidationResults();
                PrintErrors(validator.Validate());
                PrintErrors(validator.Validate(errors));
                PrintErrors(validator.ValidateTarget("powerUser01"));
                Print("Both", validator.Validate("powerUser01", errors));
            }
       
    public class MyCustomUserIdValidator : Validator
        {
            /// <summary>
            /// Initialize the object to validate.
            /// </summary>
            /// <param name="userName"></param>
            public MyCustomUserIdValidator(string userName)
            {
                Target = userName;
            }
    
    
            /// <summary>
            /// Do some custom validation on a user name(string).
            /// </summary>
            /// <param name="validationEvent"></param>
            /// <returns></returns>
            protected override bool ValidateInternal(ValidationEvent validationEvent)
            {
                string id = (string)validationEvent.Target;
                if (string.IsNullOrEmpty(id))
                {
                    validationEvent.Results.Add("Must supply a userid.");
                    return false;
                }
    
                id = id.ToLower();
                if (id == "admin" || id == "administrator")
                {
                    validationEvent.Results.Add("Admin user name is reserved, you can not use it.");
                    return false;
                }
    
                if (id.Length < 2 || id.Length > 15)
                {
                    validationEvent.Results.Add("Must be between 2 >= username <= 15.");
                    return false;
                }
                return true;
            }
        }
    

      看到这里了,前面的疑问就一下子明白,所有的自定义验证类必须继承Validator,重写ValidateInternal方法,我们可以看到Validate都会调用ValidateInternal方法,而ValidateInternal方法来做出后的处理,前面的为什么要使用ValidationEvent,也是为了使所有的扩展,使用相同的参数,相同的方法, 这样的设计固然使模块代码风格一样,最大化的提高了代码的复用率,但是是否适合自己,得靠自己来权衡。

      在认真的看完这个模块的所有设计和代码实现发现,确实做的很不错,也让我很有信心把这个用到公司的通用类库中,恩,后面还有很多,慢慢来吧罗马哪是一天能建成的~


    -----后面的模块分析停止了,写到后面几个模块的时候觉得:

      到这里的时候我觉得这个通用类库没有必要去深究其设计了,代码都设计的大同小异了,或者有某些地方的实现方法值得去研究,而且我也不想在去逐个去分析,浪费时间,而且本末倒置了,这个东西就是拿来用的~CommnLibrary中各个模块耦合性太强,想单独抠出来还不容易,很多模块项目中都用不上,如果硬拿过来,觉得只会破坏现有代码结构,到现在为之,只把Cache,Collections,Email,Extensions,Feeds,Notifications,Queue,Types,Validation,Localization,Exceptions,Utilities模块给单独抠了出来使用,罢了罢了~

  • 相关阅读:
    Spring Boot 2.x基础教程:配置元数据的应用
    目前用下来最溜的MacOS微信多开工具!
    在IDEA中通过Module管理多个项目
    JAR冲突问题的解决以及运行状态下如何查看加载的类
    完美解决方案-雪花算法ID到前端之后精度丢失问题
    精讲响应式WebClient第5篇-请求超时设置与异常处理
    精讲响应式WebClient第4篇-文件上传与下载
    精讲响应式WebClient第3篇-POST、DELETE、PUT方法使用
    精讲响应式WebClient第2篇-GET请求阻塞与非阻塞调用方法详解
    精讲响应式webclient第1篇-响应式非阻塞IO与基础用法
  • 原文地址:https://www.cnblogs.com/mmmjiang13/p/1810507.html
Copyright © 2011-2022 走看看