[C#]BlogEngine.Net架构与源代码分析系列part2:业务对象——共同的父类Busin

上篇文章朋友的评论给了我很大的动力写这个系列的文章,看来大家都比较关注这个系列。为了后续文章做一个铺垫,我在这篇文章的前半部分讲解一下BlogEngine.Net的整体架构,后半部分主要是对于BusinessBase类的分析。

     下载源代码以后打开解决方案,我们发现从项目的组织结构上BlogEngine.Net分成两个项目:一个是 BlogEngine.Core,顾名思意,它就是BlogEngine.Net的核心逻辑层。所有的业务逻辑和一些功能都在这个项目中体现,实际上这个 核心业务层中也有数据访问的一部分,那就是Provider模式。在BlogEngine.Net中,关系数据库或XML等的作用只有一个,那就是存储数 据,BlogEngine.Net的业务对象的ID生成是由核心层控制的,而不是用数据存储部分生成的,因为这样可以支持更多的数据源。它不同于很多其他 业务系统,数据库里面可能有很多存储过程,触发器,函数等来完成一定的业务运算和数据处理。在BlogEngine.Net中,我们甚至可以使用一 个.txt文件来自己开发一个Provider给BlogEngine.Net使用,方法很简单,只要实现 BlogProvider(BlogEngine.Net提供),MembershipProvider和RoleProvider就可以了,实际上 BlogEngine.Net也在很大程度上利用了.Net本身的经典模型。另外的一个项目是一个站点,主要就是具体的Web实现,但是具体的功能都是调 用核心层来完成的。

     实际上刚开始看BlogEngine.Net的源代码时我也很难入手,不知道从哪里看起,找不到入口的地方。其实也难怪,官方提供的资料 大都是关于使用和开发扩展的,社区里找到的东西也不是自己最想要的。研究了一段时间以后我发现整个BlogEngine.Net都在围绕这 BusinessBase这个基类展开,其它的类都是为它提供服务或接收它的消息,例如Provider,Extension等。 BusinessBase是所有业务类的基类,里面封装了很多业务类共有的特征。它的子类有:

AuthorProfile:用户的Profile的封装。

Page:这个类实际上是对应着BlogEngine.Net中的一篇静态文章,page和post具体区别不是很重要,感兴趣的朋友可以参照一下官方提供的说明。

Post:在BlogEngine.Net应用最多的一个类,代表作者提交的一篇文章。

Category:文章分类,一篇文章可以属于多个分类,分类之上还可以有父分类。

     下图是他们的继承关系:

     

 图中的IPublishable接口我会在以后的文章中做详细的讲解。

 从BusinessBase的原型

BusinessBase原型

我们可以看出:

1.BusinessBase是一个泛型类。这个泛型设计的很好,Type用来标识具体的子类类型,Key主要是子类对象的唯一ID,这个ID在AuthorProfile是String类型,而在Page等其它类中是Guid类型,所以定义基类时才会采取这种泛型设置。

2.BusinessBase实现的接口也是微软推荐的业务对象应该实现的接口。

IDataErrorInfo用来标识对象内部的错误信息,这个接口的实现主要用来定义某个属性的验证规则。
INotifyPropertyChanged用户通知客户端数据发生了改变。主要是对象内部数据发生改变时,对于一些绑定控件数据的同步更新。
IChangeTracking如果对象内部数据发生改变,它用来完成接收了数据的改变,包括更新数据存储等。
IDisposable这个就不用解释了吧,做.Net都知道。

     从以上我们可以看出凡是BusinessBase的子类对象都具有当修改数据时,通过属性的改变对外发出属性改变的通知,并实现 INotifyPropertyChanged来通知绑定控件,实现IChangeTracking来更新数据的存储。我们再看一下源代码发现 BlogEngine.Net将所有业务对象的数据验证交给了Validation模型来处理,这一点运用的很巧妙,统一了验证模型,我很推荐。

Validation

     那么,BusinessBase的子类都需要做什么呢?它们需要重写数 据存储的操作方法(通过Provider的调用完成,主要是DataSelect等),这也是面向接口编程所提倡的。对于内部数据的处理 BusinessBase使用了IsNew,IsChanged和IsDeleted统一了编程模型,并定义了一个SaveAction枚举来实现统一的 处理与通知消息的封装。

     BusinessBase提供了两个事件在内部数据进行存储前后触发——保存前事件和保存后事件,用来给外部提供访问点,有点类似于ASP.NET的管道 事件的东西,不过这些事件都是类的事件,并非属于某个对象。这样外部可以对于保存前的事件进行处理,也可以对于保存后的事件处理,这种模型很有利于扩展。 例如我们可以很轻松的纪录业务日志,而且纪录的很统一。此外,BusinessBase重写了相等的方法或操作符,用于两个对象的排序和比较,这都是业务 对象所共有的特性。

     那么,对于派生类从这个基类继承之后我们要实现什么呢,无非就是自己的数据存储方法,数据检验规则,自己的ID类型,还需要大家注意的就是每个派生类都提 供了一个静态属性用来提取整个对象列表,还可以根据具体的查询信息获得对象列表,不过他们都属于类的方法,也就是静态方法。对于结构和关系比较复杂的派生 类,例如Post包含了Comment列表及其相应的方法用来表示和操作对象之间的关系。此外基类的MarkOld方法用于标识这个对象已经经过了处理, 不需要在处理了,子类可以重写这个方法用于提供自己的实现。其余的一些方法或属性都是具体类中所需要的,这个很好分析。

     例如,对于客户端程序我们只要这样就可以完成数据操作:

添加文章:

Code

修改文章:

Code

删除文章:

Code

      很明显,BlogEngine.Net采用了面向对象的设计方法,事件和继承得到了很广泛的应用,此外它更好的运用了.Net平台自身 提供的模型解决问题,例如Provider模型,一些接口规范等。此外我们可以看到,BlogEngine.Net在内存中有很多对象,以空间换取时间的 处理方法在这样的系统中还是比较可靠的。

     做一些总结是很有必要的。

     上一篇:BlogEngine.Net架构与源代码分析系列part1:开篇介绍

版权声明
作者:Thriving.country
出处:http://thriving-country.cnblogs.com/
本文版权归作者和博客园共同所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接.
赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏