zoukankan      html  css  js  c++  java
  • LLBL Gen 3.x 源代码追踪与解析 验证Validation的原理和流程

    先看应用程序如何应用验证。以SalesOrderHeaderEntity为例子。
    常见的三种验证:
    1)保存之前的验证,重写ValidateEntityBeforeSave
    2) 删除前的验证,重写ValidateEntityBeforeDelete
    3) 属性获取值之后的验证,重写ValidateFieldValue

    先讲解一个基本的模式,基类中的设计virtual方法,派生中中override,我们在运行时,会调用实际类型的方法
    public class  A

       public virtual Do() {  }
    }
    public class B: A
    {  
       public override Do() { }
    }
    当以这种方法调用时
    A  obj=new B():

    obj.Do();
    它会根据obj的实际类型,调用对应的方法

    验证代码的书写

    [Serializable] 
    public partial class SalesOrderHeaderValidator : ValidatorBase 

       // __LLBLGENPRO_USER_CODE_REGION_START ValidationCode 
       删除采购单前的验证,比如采购单还在被合同contact引用,则不允许删除 
      public override void ValidateEntityBeforeDelete(IEntityCore involvedEntity) 
       { 
             base.ValidateEntityBeforeDelete(involvedEntity); 
             SalesOrderHeaderEntity salesOrder = (SalesOrderHeaderEntity)involvedEntity; 
             if (salesOrder.TotalDue != 0) 
                 throw new Exception("Total due zero not allow for this period");

        } 
       保存采购单前的验证,常常是验证必须输入值的字段

       public override void ValidateEntityBeforeSave(IEntityCore involvedEntity) 
       { 
              base.ValidateEntityBeforeSave(involvedEntity); 
              SalesOrderHeaderEntity salesOrder = (SalesOrderHeaderEntity)involvedEntity; 
              if(salesOrder.TaxAmt>1000)
                    throw new Exception("unable to deal with tax more than 1000"); 
        }  
       采购单的属性值发生改变时,应用此处的验证,比如,当获取截止日期后,要验证它不能小于当前日期

      public override bool ValidateFieldValue(IEntityCore involvedEntity, int fieldIndex, object value) 
         {
                bool result = base.ValidateFieldValue(involvedEntity, fieldIndex, value);
                if (!result)
                    return false;

                SalesOrderHeaderEntity salesOrder = (SalesOrderHeaderEntity)involvedEntity;

                switch ((SalesOrderHeaderFieldIndex)fieldIndex)
                {
                    case SalesOrderHeaderFieldIndex.DueDate:
                           return ValidateDueDate(salesOrder, (DateTime)value);            
                }
                return true;
            }

            private bool ValidateDueDate(SalesOrderHeaderEntity salesOrder, DateTime value)
            {
                if(value.CompareTo(DateTime.Now) < 0)
                    throw new Exception("Due date cannot be less than today");
                return true;
            }   
    }

    挂接到验证代码到实体中

    重写OnInitialized方法,给Validator 属性指定验证器
    protected override void OnInitialized()
    {
           base.OnInitialized(); 
            //Assign validator
           this.Validator =new SalesOrderHeaderValidator();
    }

    追踪删除采购单的堆栈

    先设计一个删除的采购单的测试方法

    [TestMethod]
    public void TestDeleteSalesOrderHeader()
    {
             DataAccessAdapter adapter = new DataAccessAdapter(ConnectionString);
             SalesOrderHeaderEntity salesOrder = new SalesOrderHeaderEntity(43659);
             adapter.DeleteEntity(salesOrder);            
    }

    进入DataAccessAdapterBase的方法
    public bool DeleteEntity(IEntity2 entityToDelete)
    {
             return DeleteEntity(entityToDelete, null);
    }

    调用它的重载overload方法

    public virtual bool DeleteEntity(IEntity2 entityToDelete, IPredicateExpression deleteRestriction)
    {

           EntityBase2 entityToDeleteAsEntityBase2 = (EntityBase2)entityToDelete;
           entityToDeleteAsEntityBase2.CallValidateEntityBeforeDelete();
    }

    进入EntityBase2的CallValidateEntityBeforeDelete
    internal void CallValidateEntityBeforeDelete()
    {
           OnValidateEntityBeforeDelete();
    }
    继续进入OnValidateEntityBeforeDelete方法
    protected virtual void OnValidateEntityBeforeDelete()
            {
                if( _validator != null )
                {
                    _validator.ValidateEntityBeforeDelete( this );
                }
            }

    至此就进入到了我在文章开头写的SalesOrderHeaderValidator的ValidateEntityBeforeDelete方法
    再来看一下ValidatorBase 中的虚拟方法ValidateEntityBeforeDelete

    [Serializable]
    public abstract class ValidatorBase : IValidator
    {

            public virtual void ValidateEntityBeforeDelete( IEntityCore involvedEntity )
            {
                // nop
            }


    验证属性值

    再来看属性设置时的验证,这种验证方法可以验证程序对采购单的任何属性的复制行为。比如,业务规则是,任何时间,采购单的截止日期都不能小于输入采购单的当天,代码如下,
    SalesOrderHeaderEntity salesOrder = new SalesOrderHeaderEntity(2068);
    salesOrder.DueDate = DateTime.Now.AddDays(-1); //这里设置DueDate 的值为昨天,违反了业务规则
    来追踪它的堆栈,进入DueDate属性的set方法

    public virtual System.DateTime DueDate
            {
                  set    { SetValue((int)SalesOrderHeaderFieldIndex.DueDate, value); }
            }

    进入EntityBase2的SetValue方法
    protected bool SetValue(int fieldIndex, object value)
            {
                return SetValue(fieldIndex, value, true);
            }

    同名的重载方法

    protected bool SetValue(int fieldIndex, object value, bool performDesyncForFKFields)
            {

                // set value is not the same as the value to set, proceed
                if(ValidateValue(fieldToSet, ref valueToSet, fieldIndex))
    进入ValidateValue方法

    private bool ValidateValue(IFieldInfo fieldToValidate, ref object value, int fieldIndex)
            {
                   // perform custom validation.
                    validationResult = (OnValidateFieldValue(fieldIndex, value));

              }
    流程进入OnValidateFieldValue方法

    protected virtual bool OnValidateFieldValue( int fieldIndex, object value )
            {
                bool returnValue = true;
                if( _validator != null )
                {
                    returnValue = _validator.ValidateFieldValue(this, fieldIndex, value );
                }
                return returnValue;
            }

    请注意看这一句returnValue = _validator.ValidateFieldValue(this, fieldIndex, value ),它会进入我在开头重写的ValidateFieldValue的方法里面,最后就是进入自定义的方法ValidateDueDate

    image

    这就是验证的完整堆栈流程。

  • 相关阅读:
    面向对象的继承关系体现在数据结构上时,如何表示
    codeforces 584C Marina and Vasya
    codeforces 602A Two Bases
    LA 4329 PingPong
    codeforces 584B Kolya and Tanya
    codeforces 584A Olesya and Rodion
    codeforces 583B Robot's Task
    codeforces 583A Asphalting Roads
    codeforces 581C Developing Skills
    codeforces 581A Vasya the Hipster
  • 原文地址:https://www.cnblogs.com/JamesLi2015/p/2157344.html
Copyright © 2011-2022 走看看