深度解析 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是个非常好的学习源码。
 
 
 


原文地址:https://www.cnblogs.com/yuanhuaming/p/1621699.html