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


你可能感兴趣的:(Engine)