云联天下首页 |  登陆 |  注册 |  密码找回 |  关于我们 | 加入收藏 
首页技术资料网站建设→DotText源码阅读(3)-框架配置体系和反序列化 【字号: 】 【背景色 杏仁黄 秋叶褐 胭脂红 芥末绿 天蓝 雪青 灰 银河白(默认色)

DotText源码阅读(3)-框架配置体系和反序列化

网址来源:http://kehui.net发布时间: 2006-12-07 00:00:16
       dottext框架配置体系 和反序列化

 

配置节是一个比较容易混淆人的专题。Dottext的系统环境配置、单独每一个人的blog配置都是通过自定义的配置节实现的,并且dottext自己实现了其中的处理程序(handler)。也就是说,利用asp.net系统的配置文件作为存储机制,加上了单独处理机制,实现了系统的灵活配置。

在web.config的根元素<configuration>下一开始就声明了自定义配置节处理程序:

<configSections>

              <section name="BlogConfigurationSettings" type="Dottext.Framework.Util.XmlSerializerSectionHandler, Dottext.Framework" />

              <section name="HandlerConfiguration" type="Dottext.Framework.Util.XmlSerializerSectionHandler, Dottext.Framework" />

              <section name="SearchConfiguration" type="Dottext.Framework.Util.XmlSerializerSectionHandler, Dottext.Framework" />

              <section name="microsoft.web.services" type="Microsoft.Web.Services.Configuration.WebServicesConfiguration, Microsoft.Web.Services, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

              <section name="codeHighlighter" type="ActiproSoftware.CodeHighlighter.CodeHighlighterConfigurationSectionHandler, ActiproSoftware.CodeHighlighter" />

</configSections>

 

其中的最后2项自然不必多讲,属于微软的提供程序和第三方提供程序,在此忽略。我们逐步来看看 Dottext.Framework.Util 下的实现过程,理解其中的逻辑。

用到的自定义处理程序都是 XmlSerializerSectionHandler ,我们看看其中的处理逻辑,蕴含的.net特性:

 

public object Create(object parent, object configContext, System.Xml.XmlNode section)

              {

                     XPathNavigator nav = section.CreateNavigator();

                     string typename = (string) nav.Evaluate("string(@type)");

                     Type t = Type.GetType(typename);

                     XmlSerializer ser = new XmlSerializer(t);

                     return ser.Deserialize(new XmlNodeReader(section));

}

string typename = (string) nav.Evaluate("string(@type)"); 是从当前XML(配置文件是一个符合xml要求的文档)节点处,获取”type”属性,然后按照属性描述,获得一个.net的类型。这里使用到了.net的反射机制。此处的type可以是类 、值类型 、数组 、接口 、指针 、枚举类型。这样,通过配置文件中的xml流(相当于字符串),系统就指定了特定的类。这种生成类的方法是区别于new 方法生成具体类的另外途径,好处就是灵活根据具体环境内容(甚至是用户交互输入的类型描述字符串)就可以生成获得托管类型。(此处反射细节请参考MSDN)。坏处就是可能隐藏着类型错误,运行时出错,导致不可预料(好像这个词在windows编程时代相当的常见)例外甚至系统崩溃。

当然,仅仅创建了类型是不够用的,还需要通过一定途径来确定生成类的具体状态,这有用到OOP语言的重要特性—序列化,将一个对象存储器来,以及从存储中还原具体对象的机制。这里使用的是System提供的 XmlSerializer 类的反序列化方法Deserialize。反序列化后面还有很多代码涉及到,我认为现在就大致理解为“通过这个反序列化,我们刚刚得到的类实例中的属性、成员变量获得了赋值,进入到某个状态,就好像我们此处运行了new 语法和进行了对象的构造以及赋值”即可。更进一步的可以从权威资料MSDN获取。

 

基于以上理解,我们来阅读相关的配置节,并进行解释。

从简单的入手:

<SearchConfiguration type="Dottext.Search.SearchConfiguration, Dottext.Search" urlFormat="http://{0}/{1}/{2}/{3}.aspx"

              virtualPath ="~/SearchIndex" physicalPath="SearchIndex" domains="localhost"

              pageSize="20" />

这个配置节,定义了一个 在Dottext.Search程序集中存在的名为“Dottext.Search.SearchConfiguration”的类,在反序列化的时候,我们会对其中的某些属性(urlFormat、virtualPath、physicalPath、domains、pageSize )进行赋值。那么,这些可以反序列化的类有否什么区别于其他“正常类”的地方呢?我们打开这个类看看:

[Serializable]       //注意,这里用到的是属性编程,这个是.net的新特性,通过这个语法声明了名为Serializable的属性给类 SearchConfiguration,告诉.net框架这个类是可以进行序列化和反序列化。默认情况下,所有该类的字段(包括私有)都要序列化和反序列化,但是通过另外指定属性声明,可以灵活处理。

       public class SearchConfiguration

       {

              public static readonly string PermaLink = "permalink";

              。。。。。。//一大堆只读静态字段

              public static readonly string TempIndex = "tempIndex";

             

              public static SearchConfiguration Instance()

              {

                     return (SearchConfiguration)ConfigurationSettings.GetConfig("SearchConfiguration");

//此处就是利用了反射来构造类实例。

              }

 

              public SearchConfiguration()

              {                     //缺盛构造函数

              }

 

              private string _urlFormat = "http://{0}/{1}/{2}/{3}.aspx";

              [XmlAttribute("urlFormat")]       //此处另外声明了UrlFormat属性的序列化和反序列化属性,告诉.net运行时环境此处的字段采用XML节点作为存储进行序列化和反序列化,并且读取的节点名称是“urlFormat”。

              public string UrlFormat

              {

                     get {return this._urlFormat;}

                     set {this._urlFormat = value;}

              }

 

              private string _domains;

              [XmlAttribute("domains")]

              public string Domains

              {

                     get {return this._domains;}

                     set {this._domains = value;}

              }

 

              private int _rebuildInterval = 60;                    

              [XmlAttribute("rebuildInterval")]

              public int RebuildInterval

              {

                     get {return this._rebuildInterval;}

                     set {this._rebuildInterval = value;}

              }

 

              private int _updateInterval = 30;             

              [XmlAttribute("updateInterval")]

              public int UpdateInterval

              {

                     get {return this._updateInterval;}

                     set {this._updateInterval = value;}

              }

 

              private int _pageSize = 50;         

              [XmlAttribute("pageSize")]

              public int PageSize

              {

                     get {return this._pageSize;}

                     set {this._pageSize = value;}

              }

 

              private int _searchResultLimit = 100;       

              [XmlAttribute("searchResultLimit")]

              public int SearchResultLimit

              {

                     get {return this._searchResultLimit;}

                     set {this._searchResultLimit = value;}

              }

 

              private string _virtualPath;             

              [XmlAttribute("virtualPath")]

              public string VirtualPath

              {

                     get {return this._virtualPath;}

                     set {this._virtualPath = value;}

              }

 

              private string _physicalPath;         

              [XmlAttribute("physicalPath")]

              public string PhysicalPath

              {

                     get

                     {

                            if(this._physicalPath == null)

                            {

                                   if(VirtualPath != null)

                                   {

                                          this._physicalPath = HttpContext.Current.Server.MapPath(VirtualPath);

                                   }

                                   else

                                   {

                                          throw new ApplicationException("Physical location of the search index could not be found. Either the physical or virtual location must be specified in your configuration file");

                                   }

                            }

                            return this._physicalPath;

                     }

                     set {this._physicalPath = value;}

              }

       }

 

如果哪一个字段不需要参与序列化和反序列化,应该指定[XmlIgnore]属性标记。

 

接下来,看看后面经常用到的 BlogConfigurationSettings ,该类为“Dottext.Framework.Configuration.BlogConfigurationSettings”,察看该类源代码,我们发现该类也是可序列化和反序列化的。不过注意的是,其中的部分成员属于数组,而数组属于复合数据类型,所以在配置文件声明中是这样的:

<EntryHandlers>

                     <EntryHandler type="Dottext.Framework.EntryHandling.CommentFormatHandler, Dottext.Framework" postType="Comment"       processAction="Insert" processState="PreCommit" isAsync="false" />

                     <EntryHandler type="Dottext.Framework.EntryHandling.CommentDeliveryHandler, Dottext.Framework"       postType="Comment" processAction="Insert" processState="PostCommit" isAsync="true" />

                      ……

</EntryHandlers>

而在类源代码中是这样的来说明改成员:

private EntryHandler[] _entryHandlers;

[XmlArray("EntryHandlers")]

public EntryHandler[] EntryHandlers

{

       get {return this._entryHandlers;}

       set {this._entryHandlers = value;}

}

通过XmlArray属性,指出了要按照数组方式进行序列化和反序列化,节点的名称是“EntryHandlers”。.net CLR会通过反射机制将配置文件的描述生成EntryHandler[],而其中每一个元素都是Dottext.Framework.EntryHandling.CommentDeliveryHandler,这个过程通过一个短小的[XmlArray("EntryHandlers")]就完成,且又达到了灵活是应需求,展示了.net提供的新特性的威力。HandlerConfiguration也是通过配置获得一个数组,类似机理。

另外,打击需要着重看看

<BlogProviders>

                     <!-- Controls how .Text formats Urls -->

                     <UrlFormatProvider type="Dottext.Framework.Format.UrlFormats, Dottext.Framework" />

                     <DTOProvider type="Dottext.Framework.Data.DataDTOProvider, Dottext.Framework" />

                     <!--

                                   By default .Text uses SQL Server as the backend data store. The DbProvider determines which DbProvider

                                   (a class which implements IDbProvider) is used. This is optional.

                     -->

                     <DbProvider type="Dottext.Framework.Data.SqlDataProvider, Dottext.Framework" connectionString="user id=ad;password=cbiqadjsd;initial Catalog=Zixun_dataBase;Data Source=211" />

                     <ConfigProvider type="Dottext.Common.Config.MultipleBlogConfig, Dottext.Common" host="localhost"       cacheTime="120" />

                     <!--

                     <ConfigProvider type = "AspNetWeb.MSBlogsConfigProvider, MsftBlogsHttpModule"

                            cacheTime = "120"/>

                     -->

                     <!-- Controls how .Text sends email. By default, SystemMail is used. -->

                     <EmailProvider type="Dottext.Framework.Email.SystemMail, Dottext.Framework" smtpServer="localhost"       adminEmail="EMAIL" />

              </BlogProviders>

此处的配置信息在后面的很多部分都涉及到。看看BlogProviders类(呵呵,当作课外吧),也是一个可序列化和反序列化的类。

整个dottext很多灵活性就是通过这机制体现。

 





shanhe 

相关新闻
v Asp.net服务器控件编程(1) 开篇、基础 2006-12-07 00:00:16
v 也为CSDN Blog加效果 2006-12-07 00:00:16
v 受Ruby on Rails影响的PHP开发框架 2006-12-07 00:00:16
v webpartzone无法显示最小化和关闭按钮? 2006-12-07 00:00:16
v 各类WEB建设环境开发平台的搭建 2006-12-07 00:00:16
v 在网页中插入视频播放代码全集 2006-12-07 00:00:16
v 三种主流动态网页制作技术比较之我见 2006-12-07 00:00:16
v Apache、php、mysql(最新安装版) 2006-12-07 00:00:16
v APACHE2.02+PHP5+mysql5配置 2006-12-07 00:00:16
v PhotoShop快捷键[推荐] 2006-12-07 00:00:16
  最新新闻
智慧家居
智慧家居颠覆传统智能家居
智慧云谷让智能家居变成有智慧的
智慧云谷引领智慧家居新生活
科技改变生活 智慧云谷智慧家居系
智慧家居领航者,智慧云谷助你玩
智能家居如何赢得市场美誉度?
智慧云谷智慧家居:创业者有无限
WiFi智能家居你还在用?这样的智
互联网+助推智能家居产业
智慧云谷为您打造真正的智能家居
智能家居产业需要的不是单品,而
新家如何选择开关?智慧云谷iWis
智能传感器-世界首款“智”为你的
智慧云谷开关智能安防智能空气质
智能开关品牌,如何选择智能开关
秋季干燥,智慧家居温湿度传感器
传感器助力智慧家居 感知爱家
iWiscloud智能触摸开关缔造家居装

  最新帖子
 ※室内空气污染的危害及  [sensor]
 ※超声波风速传感器在生  [sensor]
 ※这么冷清  [gabc111]
 ※手机APP操作有问题  [ssy11407]
 ※智慧云谷智慧家居将在  [cici]
 ※上传下载  [cici]
 ※下载智慧家居  [apple2008]
 ※秋季干燥,智慧家居温  [apple2008]
 ※智慧家居紧扣热点 安全  [apple2008]
 ※办公大楼如何智慧化管  [apple2008]
 ※智慧云谷工业自控的优  [apple2008]
 ※传感器助力智慧家居 感  [apple2008]
 ※智能开关品牌,如何选  [apple2008]
 ※智慧云谷开关智能安防  [apple2008]
 ※没有专业人员,如何安  [apple2008]
 ※烟台智慧云谷董事长任  [apple2008]
 ※互联网+助推智能家居产  [apple2008]
 ※WiFi智能家居你还在用  [apple2008]
 ※智慧云谷智慧家居:创  [apple2008]
 ※智能家居如何赢得市场  [apple2008]
钯碳回收 硝酸银回收 银浆回收 银焊条回收 回收银浆 氯化钯回收 氯化钯回收 氧化钯回收 回收硝酸钯 钯水回收价格 海绵钯回收 钯炭回收价格 回收镀金板 深圳钯碳回收 镇江氯化钯回收 杭州钯浆回收 银浆回收多少钱 回收钯碳公司 硝酸银的价格 那里有回收金 氯化钯回收价格 江苏擦银布回收 硝酸银价格 德州钯粉回收 银铜回收 回收钯粉 回收铂碳催化剂 佛山钯碳回收 金盐回收价格 海绵钯回收 钯碳高价回收 钯回收价格 钯炭回收