• 深度解析 BlogEngine.Net


        最近买了本 C#2005 Business Objects  基于一个CSLA.NET开源项目展开的。大致看了下,觉得比较深奥。需要结合CSLA源码。不过在深入源码之前我决定先复习一个BlogEngine.Net。BlogEngine得核心类可以理解为是CSLA的阉割版。

    BusinessBase 是BlogEngine所有业务的基类。

    1.首先我们看下它继承了那些接口

    public abstract class BusinessBase<TYPE, KEY> : IDataErrorInfo, INotifyPropertyChanged, IChangeTracking, IDisposable where TYPE : BusinessBase<TYPE, KEY>, new()

     

    1.1  IDataErrorInfo 

    该功能提供用户界面可以绑定的自定义错误信息。

    这个接口虽然被实现。我发现没有使用,不清楚作者如何处理了。

    1.2 INotifyPropertyChanged

    向客户端发出某一属性值已更改的通知。

    /// <summary>
    /// Occurs when this instance is marked dirty.
    /// It means the instance has been changed but not saved.
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    MSDN:  ms-help://MS.MSDNQTR.v90.chs/fxref_system/html/d7424bfd-9de2-e553-d64e-57a78a2134d4.htm

    INotifyPropertyChanged 接口用于向客户端(通常是执行绑定的客户端)发出某一属性值已更改的通知。

    例如,考虑一个带有名为 FirstName 属性的 Person 对象。若要提供一般性属性更改通知,则 Person 类型实现 INotifyPropertyChanged 接口并在 FirstName 更改时引发 PropertyChanged 事件。如果数据源实现 INotifyPropertyChanged 并且您执行的是异步操作,则不得在后台线程上对数据源进行更改。相反,应在后台线程上读取这些数据并将这些数据合并到 UI 线程上的列表中。

    若要在将客户端与数据源进行绑定时发出更改通知,则绑定类型应具有下列任一功能:

    • 实现 INotifyPropertyChanged 接口(首选)。

    • 为绑定类型的每个属性提供更改事件。

     

     

    1.3 IChangeTracking

    定义查询对象更改以及重置更改后的状态的机制。

    我也没有发现任何调用。

     

    1.4 IDisposable

    这个大家都很熟悉了

    1.5 where TYPE : BusinessBase<TYPE, KEY>, new()

    所有业务类都必须继承这个BusinessBase,否则vs就会送你个error。

     

    2.BusinessBase具有那些功能

    2.1 获取对象的状态

    2.1.1 IsNew 

    private bool _IsNew = true; 

    初始化=true

    True: 说明这个对象是新创建的 

    False:说明已经存在这个对象了

     

    2.1.2 IsDeleted,IsChanged

    也是用来做判断标记

     

    2.2 Validation 规则

      IsValid 标记 是否需要验证。

    ValidationRules()方法为虚方法。也是在继承类中实现,看下BlogRollItem.cs代码

    AddRule()方法中最后一个参数确定了是否应用这些规则。

            private StringDictionary _BrokenRules = new StringDictionary();

            /// <summary>
            /// Add or remove a broken rule.
            /// </summary>
            /// <param name="propertyName">The name of the property.</param>
            /// <param name="errorMessage">The description of the error</param>
            /// <param name="isBroken">True if the validation rule is broken.</param>
            protected virtual void AddRule(string propertyName, string errorMessage, bool isBroken)
    10         {
    11             if (isBroken)
    12             {
    13                 _BrokenRules[propertyName] = errorMessage;
    14             }
    15             else
    16             {
    17                 if (_BrokenRules.ContainsKey(propertyName))
    18                 {
    19                     _BrokenRules.Remove(propertyName);
    20                 }
    21             }
    22         }
    23
    24         protected abstract void ValidationRules();
    25
    26         public bool IsValid
    27         {
    28             get
    29             {
    30                 ValidationRules();
    31                 return this._BrokenRules.Count == 0;
    32             }
    33         }


    BlogRollItem.cs

    1         protected override void ValidationRules()
    2         {
    3             AddRule("Title", "Title must be set", string.IsNullOrEmpty(Title));
    4             AddRule("BlogUrl", "BlogUrl must be set", BlogUrl == null);
    5         }

    最后在提交按钮之前做了处理  ,代码截取了片段

    ValidationMessage 是将错误信息写成字符串的一个方法

    BusinessBase .cs

            public virtual SaveAction Save(string userName, string password)
            {

                if (IsDeleted && !(IsAuthenticated || isValidated))
                    throw new System.Security.SecurityException("You are not authorized to delete the object");

                if (!IsValid && !IsDeleted)
                    throw new InvalidOperationException(ValidationMessage);

    10             return SaveAction.None;
    11         }

     

    2.3 通用数据访问

    运用了模板模式,在其继承类实现DataSelect方法。调用其继承类的A类的方法只需XXX.Load(id).

    而无需在A类设定对象的状态,体现了代码的高度重用。

    代码如下:

            /// <summary>
            /// Loads an instance of the object based on the Id.
            /// </summary>
            /// <param name="id">The unique identifier of the object</param>
            public static TYPE Load(KEY id)
            {
                TYPE instance = new TYPE();
                instance = instance.DataSelect(id);
                instance.Id = id;
    10
    11             if (instance != null)
    12             {
    13                 instance.MarkOld();
    14                 return instance;
    15             }
    16
    17             return null;
    18         }
    19        
    20                 /// <summary>
    21         /// Retrieves the object from the data store and populates it.
    22         /// </summary>
    23         /// <param name="id">The unique identifier of the object.</param>
    24         /// <returns>True if the object exists and is being populated successfully</returns>
    25         protected abstract TYPE DataSelect(KEY id);

    再看一个方法:

            /// <summary>
            /// Saves the object to the data store (inserts, updates or deletes).
            /// </summary>
            public virtual SaveAction Save(string userName, string password)
            {
                bool isValidated;
                if (userName == string.Empty)
                    isValidated = false;
                else
    10                 isValidated = Membership.ValidateUser(userName, password);
    11
    12             if (IsDeleted && !(IsAuthenticated || isValidated))
    13                 throw new System.Security.SecurityException("You are not authorized to delete the object");
    14
    15             if (!IsValid && !IsDeleted)
    16                 throw new InvalidOperationException(ValidationMessage);
    17
    18             if (IsDisposed && !IsDeleted)
    19                 throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "You cannot save a disposed {0}", this.GetType().Name));
    20
    21             if (IsChanged)
    22             {
    23                 return Update();
    24             }
    25
    26             return SaveAction.None;
    27         }

    也是运用了模板模式,和上一段代码的区别在于使用了虚方法。

     
    总结:BlogEngine.Net是个非常好的学习源码。
     
     
     


  • 相关阅读:
    Extjs 中combobox下拉框初始化赋值
    关于继承的理解
    近来很郁闷
    Java String 常量池理解
    关于时间复杂度的讲解
    List、Set和数组之间的转换(转载)
    提升自我修养的具体方法有哪些?
    Mapped Statements collection does not contain value fo
    io流导出csv
    反射,System.Type类
  • 原文地址:https://www.cnblogs.com/yuanhuaming/p/1621699.html
Copyright © 2020-2023  润新知