开源内容管理系统DOTNETNUKE的研究与应用

开源内容管理系统DOTNETNUKE的研究与应用

李佳,李晓风,桂杰,唐磊

(安徽光学精密机械研究所 网络中心,安徽 合肥 230031

lijia@hfcas.ac.cn

摘要:DOTNETNUKE(简称DNN)是国外的开源内容管理系统。本文分析了构成DNN系统的三层结构,并对其中的关键技术数据提供者模式做深入分析。最后将这种设计模式方法应用在一般的WEB应用程序中,使之在底层数据库更换方面具备了与DNN同样的灵活性。

关键字DNN;系统结构;数据提供者模式

中图法分类号TP393.09    文献标识码A

Research and Application of Open Content Management System DOTNETNUKE

LI Jia,LI Xiao-feng,GUI Jie,TANG Lei

(Anhui Institute of Optics and Fine Mechanics , Network Center , Hefei Anhui 230031, China )

Abstract DOTNETNUKE (DNN in short) is a foreign open source content management system .This paper analyzed the three layers structure of DNN system,and also anlyzed one of its key technologes data provider pattern in depth.In the end,this design pattern had been applied to a normal WEB Application to make it has the same flexibility as DNN in area of replacing database in bottom layer.

Key wordsdnn; system structure; data provider pattern

 


0        引言

 

DotNetNuke(简称DNN)是一个免费、开源、可扩展的内容管理系统。可广泛应用于商务网站、企业内网(Intranet)和外网网站、在线内容发布网站。是建立在微软ASP.NET平台之上的一套Web应用框架。笔者已应用该系统成功的搭建出多个站点:强磁场研究中心(http://hhmfl.hfcas.ac.cn/);环境光学与技术重点实验室(http://www.leot.ac.cn;自定义新闻发布模块的测试站点(http://www.leot.ac.cn/hfcas)以及正在建设中的中科院合肥物质研究院和安徽循环经济技术工程院网站。国内也涌现出大量应用DNN搭建的门户网站,如http://www.dnnchina.net等,但一直缺少对DNN系统本身全面和深入的研究。本文旨在分析这一开源系统的架构并对其中的一个关键技术做深入的研究和应用

 

1 DNN概述

 

11 DNN发展简史

DNN是加拿大人Shaun Walker发起并创立的遵从BSD协议的开源项目。其前身是IBuySpy PortalIBuySpy Portal是微软当初为了鼓励开发者使用.Net Frame Work 1.0 Beta这项新技术而创建的开源项目。Shaun Walker在此项目基础上开发和增加了新的功能使得在线建立网站变成了件容易的事情,并于02年底将其发布为IBuySpy WorkShop,此版本就是DNN的雏形。033IBuySpy WorkShop version 1.0.5 被赋予新的项目名称DotNetNuke043DNN 2.0发布,比起最初的版本,DNN2.0在核心结构和安全性上做出了较大的修改,在模块,皮肤,模板,数据接口以及本地化方面提供了更好的扩展性。048DNN3.0发布,新增了例外处理和事件日志的功能,并率先在核心结构中集成了ASP.NET2.0 Membership APIs0512DNN4.0发布,此版本完全基于ASP.NET2.0技术平台。

DNN是一个伴随微软.NET技术不断发展的开源项目,其官方站点是http://www.dotnetnuke.com。目前最新的版本是DNN 4.3.4 。本文所阐述的内容是围绕DNN3.1.1展开的。

12 DNN的特点

n                       开源–DotNetNuke是免费的开源的软件, 用户协议基于BSD 风格的协议。 允许用户在此项目上进行任何商业和非商业的运作。

n                       可扩展–DotNetNuke可以通过内置工具创建极其复杂的内容管理系统, 同时管理员也可以使用其它的工具, 第三方的工具, 和自定义模块。站点自定设置和功能实现是没有限制的。

n                       公认的–DotNetNuke是一个商标, 在开源社区被熟知和认同的品牌。在线注册用户和开发高手超过125,000DotNetNuke还将通过广泛参与、真实条件下的应用、和最终用户的反馈进一步开发。

 

2 DNN系统结构

 

系统采用B/S结构,其中服务器端可划分成Web服务器和数据库服务器。服务器端采用面向对象的三层结构,提高了系统的可维护性和扩展性。通过分析DNN架构方式可为我们构建类似项目提供了很好的参考模板。

1 DNN系统结构图

其中Web 服务器端按逻辑可划分成表示层(Presentation Layer;业务逻辑层(Business Logic Layer;数据访问层(Data Access Layer)。

2.1表示层(PL)

表示层直接面向用户,是客户访问DNN站点的接口。这一层由以下元素构成:

n                       Web表单(Web Forms):不同于一般ASP.NET网站,为每一个网页建立Web表单,DNN中唯一的Web表单是Default.aspx,它是站点的起始页同时也承载了表示层中其它元素,在DNN站点中起着置关重要的作用。

n         皮肤(Skins)和容器(Containers):这里的皮肤和容器分别指网页和模块的外观,DNN采用了装饰器模式使得内容和显示样式的功能分离,Default.aspx根据用户的设置加载相应的皮肤和容器。

n         模块用户控件(Module User Controls):模块是构成DNN的基本元素,它在表示层的呈现形式是用户控件(Module user control),Default.aspx通过加载模块用户控件为用户提供访问模块功能的接口。

n         客户端脚本(Client-Side Script):当表示层和客户端需要更及时和灵活多样的交互形式时可以引用用JavaScript编写的客户端脚本。

2.2业务逻辑层(BLL)

业务逻辑层由三部分组成:自定义业务对象(CBO);CBO控制器(CBO Control);抽象类数据提供者(Data Provider)。CBO完全由属性构成,CBO控制器则完全由方法构成。Data Provider是数据访问层的父类,包含了一个工厂方法,通过反射技术调用数据访问层中具体的方法为CBO提供源数据。DNN采用DataReader这个ADO.NET中的组件作为数据访问层和业务逻辑层间的数据传输工具,DataReader是单向只读数据流。为了减少将DataReader中的每个字段值赋给CBO属性的代码量,DNN提供了名为CBO Hydrator的专门类,其中的方法FillObject(ByVal dr As IDataReader, ByVal objType As Type)DataReader数据流赋给单个CBO对象实例;FillCollection(ByVal dr As IDataReader, ByVal objType As Type)DataReader数据流赋给一系列CBO对象实例。

建立中间业务层主要有两方面的好处:一是出于类型安全的考虑;二是降低了表示层应用程序同底层存储数据间的耦合性。所谓类型安全的问题是指如果直接将DataReader中的字段值赋给表示层应用程序变量可能会造成类型不匹配,而且这种错误是发生在运行时的,在编译阶段无法查错,即造成类型的不安全。建立业务逻辑层后,可将CBO对象的属性值赋给变量,这样类型不匹配的问题就不会在运行时才发现,编译器可以即使发现问题。另一方面,良好的面向对象的设计思想希望应用程序同它存储数据之间的依赖关系不强。业务逻辑层的抽象类DataProvider正是起到了降低耦合性的隔离作用,CBO控制器中的方法直接调用的是DataProvider中的抽象方法,因此当数据访问层的具体实现发生变化时,业务层的代码无须更改。关于DataProvider和数据访问层的关系将在数据提供者模式一节中详细论述。

2.3数据访问层(DAL)

数据访问层的数据访问类是业务逻辑层抽象类Data Provider的子类,是对Data Provider中的抽象方法的具体实现,提供了访问数据库的具体方法,是与物理数据库紧密耦合的一层。

 

3 DNN中的数据提供者模式

 

DNN作为开源项目不仅给开发者提供了良好的搭建网站的平台,同时通过分析其代码可以学习到其中很多优秀的设计模式思想。

设计模式

用途

提供者模式

创建数据提供者日志记录器HTML编辑器提供者等

装饰器模式

实现模块与模块容器的分离,更换皮肤

组合模式

组成栏目菜单

共享对象

采用缓存保存公用对象

桥接模式

多种日志记录

策略模式

实现HTML编辑器的互换

观察者

模块间的事件管理

适配器

读取不同版本模块的安装配置文件

1 DNN所采用的部分设计模式方法

下面将着重分析提供者模式在DNN中的应用。

3.1提供者模式(Provider Model

软件设计的目标之一是保证软件的可维护性,即在需求变化或演化时,能在可预计的时间和成本范围内完成软件扩充。具体的说就是要遵从“开-闭”原则:软件实体应对扩展开放,对修改关闭。

提供者模式为开发者提供了这样的一种可行性:在对业务逻辑层的业务对象进行业务逻辑设计时可以不必关心实现这种业务逻辑关系的底层细节。所谓“提供者(Provider)”是指应用程序接口(API)同业务逻辑之间的约定,这个约定确定了具体的应用程序接口实现(implement of the API)应该提供的功能。当应某种业务需求而调用API中的一个方法时,API的实现就会完成这种需求的实现,而API本身并无须知道这个需求实现的过程是怎样的。提供者模式是对“面向接口编程”思想的具体实现,面向接口编程要求针对接口,而不是具体实现,系统可维护性大大增强。

实现提供者模式的关键是让应用程序接口(API)和API实现的分离。具体的说API可以是一个抽象类,它不会因为实现它的具体类的改变而变化。因此抽象类API会显示更好的文档结构和扩展性,也更容易被阅读和理解。

DNN在以下方面用到了提供者模式:数据提供者(Data Provider;计划提供者(Scheduling Provider;日志提供者(Logging Provider;HTML编辑器提供者(HTML Editor Provider;搜索提供者(Search Provider;友好URL提供者(Friendly URL Provider)。

本文将着重分析数据提供者模式的实现细节。

3.2数据提供者(Data Provider

如前所述DNN在业务逻辑层和数据访问层间应用了数据提供者模式,使得DNN可以更换底层数据库而不必修改业务逻辑层的代码。

3 DNN系统进行数据访问的逻辑流程图

数据提供者模式主要由以下两部分构成:

n                       数据提供者应用程序接口(Data Provider API):是一个抽象基类DataProvider

n                       数据提供者应用程序接口的实现(Implementation of Data Provider API):具体的数据库访问类,是Data Provider 的子类。

实现数据提供者模式的技术关键有两方面:一是如何实现数据提供者应用程序接口(API)和API实现的分离?DNN将它们分属于不同的组件(Assembly,分别编译。当具体的数据库访问类发生变化时,只需对其重新编译而无须重新编译应用程序主体(UIBLL),提高了系统的可维护性。如DNN应用程序主体所属组件是dotnetnuke.dll,数据库访问类所在组件是dotnetnuke.sqldataprovider.dll,当我们需要将DNN的底层数据库更换为Access时,只要重新编译新的数据库访问类生成dotnetnuke.accessdataprovider.dll。二是如何实例化数据提供者应用程序接口的实现的对象;如果是业务逻辑层直接实例化的话,破坏了面向接口编程的原则以及APIAPI实现分离的原则。为此我们需要一个专门实例化对象的类——工厂,并采用.NET反射技术在运行时才实例化对象。即使用反射工厂方法来实例化具体的数据库访问类。

3.2.1 .NET反射工厂方法

数据提供者应用程序接口DataProvider不仅是抽象数据库访问基类同时也是实例化具体数据库的工厂。它提供了实例化具体数据库访问对象的工厂方法。DataProvider中的工厂方法是静态过程Static viod CreateProvider()。这个工厂方法调用反射类中的CreateObject函数动态的生成实例对象。CreateObject有如下两种重载形式: 1.DotNetNuke.Framework.Reflection.CreateObject(“data”);

2.DotNetNuke.Framework.Reflection.CreateObject(data,Cross.DNN.Modules.CrossArticle.Data, Cross.DNN.Modules.CrossArticle));

实现反射的关键是要提供所要创建实例的类型名称。类型名称(TypeName)由两部分组成,第一部分是包含了完整名称空间(namespace)的类名,第二部分是类所在的组件(Assembly)的名称。上面的两种重载形式对应着两种获得类型名称的方法。

由于采用反射技术在运行时才知道要所要实例化的相关信息,因此这些信息不可以固化在程序中。DNN所采用的是在配置文件(web.config)中定义了数据提供者应用程序接口实现的配置信息,并提取这些信息到相应的类中。配置文件中针对不同的提供者模式定义了相应的节(section,如数据提供者模式所对应的节就是”data”。以下呈现的就是配置文件中”data”节的相关信息:

1.                  Section Handle<section name=”data” type=”DotNetNuke.Framework.Providers.ProviderConfigurationHandler, DotNetNuke” />

2.                  Section

<data defaultProvider=”SqlDataProvider”>

      <providers>

        <clear />

        <add name=”SqlDataProvider” type=”DotNetNuke.Data.SqlDataProvider, DotNetNuke.SqlDataProvider” connectionStringName=”SiteSqlServer” upgradeConnectionString=”” providerPath=”~/Providers/DataProviders/SqlDataProvider/” objectQualifier=”” databaseOwner=”dbo” />

      </providers>

</data>

Section Handle的作用一是标明了具体配置节(section)的名称;二是在type属性中提供了提取配置信息对象的类型名称,即位于DotNetNuke.Framework.Providers 名称空间下的ProviderConfigurationHandler 类,它所属于的组件名称是DotNetNuke 。该类实现了IconfigurationSectionHandler接口返回ProviderConfiguration 对象,ProviderConfiguration 类中有两个重要的属性:DefaultProviderProviders属性,即对应着data节中的内容。其中DefaultProvider属性的类型是字符串,存储了<data>defaultProvider属性值;Providers属性的类型是哈希表(hashtable),存储了<providers>下子节<add>的信息,hashtable的数据结构是名/值对,其名称对应着<add>节属性name的值,值则对应着<add>节所有属性名/值对构成的属性集合即XmlAttributeCollection数据类型。这个类型的对象是作为Provider类构造函数的参数实例化Provider对象的。Provider对象提供了三个属性:Name,Type,Attributes分别对应着<add>节中的name属性值,type属性值,以及其它属性名/值对构成的集合即NameValueCollection对象。具体的数据库访问类就是通过Provider类的Attributes属性获得数据库信息的。

Reflection类中用第一种方法生成对象时,首先将参数data传递给函数ConfigurationSettings.GetConfig,这个.NET自带的静态函数根据参数dataweb.config中定位到相应的Section Handle并调用这个Section Handle返回ProviderConfiguration对象objProviderConfiguration。然后将objProviderConfiguration.Providers(objProviderConfiguration.DefaultProvider)作为构造函数的参数实例化一个Provider对象。所要生成的对象的类型名称即由Provider对象的Type属性提供。

第二种方法获得ProviderConfiguration对象的过程和第一种方法相同。然后将第二和第三个参数分别加上后缀字符串ProviderConfiguration对象的DefaultProvider属性值构成所要生成的对象的类型名称。这种方法用于实例化DNN模块的具体数据库访问类。由于DNN模块可由第三方开发,模块的名称空间和组件名称等可以自定义,不可能针对每一个自定义模块都在web.config中定义与其相关的配置信息。因此采用第二种方法,只要把自定义的名称空间和组件名称作为参数传递给反射工厂方法即可得到需要实例化的类型名称。而DNN系统的核心功能模块则采用第一种方法。

Reflection类除了从配置文件提取信息获得类型名称并创建相应的实例外,还将这个实例放入缓存Cache中以提高系统性能。如果不采用反射技术,只使用一般的工厂方法。当新增一个数据库类型时就要新增一个具体工厂,从而需要重新编译主程序,降低了应用程序的可维护性。

3.2.2 应用数据提供者模式数据访问流程

为了实现某个业务逻辑,业务逻辑对象控制器(CBO Controller)通过抽象类Data Provider提供的接口,以及.Net反射技术动态的调用具体数据库访问类中的相应方法。

CBO Controller本身无须了解实现这个接口的细节。当需要更换底层数据库时所要做的是在配置文件中关于<data>节的<providers>子节下添加新的数据库的配置信息,并修改data节的defaultProvider属性值为新数据库配置信息节的名称值(name;然后创建新的具体数据库访问类,并编译这个类即可。这个过程中主程序无须做任何修改和重编译,体现了良好的系统可维护性和可扩展性。

 

4 提供者模式在普通ASP.NET应用程序中的应用

 

通过对DNN项目中提供者模式的研究,笔者成功的在一个模拟银行帐单交易的ASP.NET应用程序中实现的数据提供者模式,使其底层数据库能方便在Access数据库和SqlServer数据库之间互换。

这个应用程序只在数据访问层应用了提供者模式,即在抽象类Data provider中调用反射工厂方法动态生成具体数据库访问类的实例,因此web.config中的配置信息做了简化,不再建立专门的配置信息类,web.config中只在<appSetting>节中添加了两个子节配置相关数据库的信息:

<add key= connString value=Server=(local);Database=Banking;uid=sa;pwd=;/>

<add keyDefaultDataProvider value=sqlDataProvider/>

以上代码提供了数据库为sqlserver时的配置信息,当数据库换为Access时,配置信息可更换成以下代码:

<add key="datasource" value="Provider= Microsoft.Jet.OLEDB.4.0;Data Source=F:/asp/day8/data/banking.mdb"/>

<add key="DefaultDataProvider" value="AccessDataProvider"/>

在反射工厂方法中通过采用了第二种方法实例化具体数据库访问类,只是取消了第一个参数,默认数据提供者的信息由ConfigurationSettings.AppSettingsDefaultDataProvider)获取。

在具体数据库访问类中通过ConfigurationSettings.AppSettingsconnString)获取数据库的连接字符串,并根据具体数据库的不同实现实现具体的方法。

 

4 结语

本文概述了开源内容管理系统DNN系统架构,对其中关键技术之一数据访问所采用的数据提供者模式着重分析并将其简化和改进用于一般web应用程序,为相关的WEB应用系统的开发提供了范例。

 

参考文献

[1] SHAUN WALKER, PATRICK. J. SANTRY, JOE BRINKMAN, DANIERL CARON,

SCOTT MCCULLOCH, SCOTT WILLHITE, BRUCE HOPKINS. Professional DotNetNuke ASP.NET Portals[M]. Indianapolis : Wiley Publishing,2005.

[2] 甄镭..NET与设计模式[M].北京:电子工业出版社,2005.91-97

[3] 谭立球,费耀平,李建华,高淡.多网站内容管理系统的设计和实现[J].计算机应用,2004,24(11):4-6.

[4]吕西红,陈志刚,曾碧卿,曾志文.三层客户/服务计算技术研究及应用[J].计算机工程与应用,2005,(34):120-123.

[5] MICHAEL DUELL.Catalog of Non-Software Examples of Design Patters

[J].Object Magazine,1997,(7)52-57.

作者简介 李佳(1982),,安徽合肥人, 硕士研究生,研究方向为计算机应用;李晓风(1966-),男,安徽砀山人,研究员,硕士生导师,主要研究方向计算机控制、软件工程、计算机应用等;桂杰(1982-),男,江苏泰州人,硕士研究生,研究方向为计算机应用;唐磊(1981), 男,安徽淮北人, 硕士研究生,研究方向为计算机应用。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值