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很多灵活性就是通过这机制体现。

转载于:https://www.cnblogs.com/jasononline/archive/2007/06/01/767192.html

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

  1. 推荐系列文章:《DotText源码阅读》

    DotText源码阅读 作者:shanhe DotText源码阅读(0) DotText源码阅读(1)-调试 DotText源码阅读(2)-工程.数据库表结构 DotText源码阅读(3)-框架配置体 ...

  2. DotText源码阅读(7) --Pingback/TrackBack

    DotText源码阅读(7) --Pingback/TrackBack 博客这种服务的区别于论坛和所谓文集网站,很大程度上我认为是由于pingback/trackback的存在,使得博客这种自媒体有可 ...

  3. openlab的源码阅读——config文件配置

    openlab源码阅读--config文件配置 把config文件单独摘出来放在了CSDN上--https://download.csdn.net/download/qq_32651847/85321 ...

  4. D - JDK17源码阅读 - 集合框架 - Collection<E> 接口 - 集合框架核心接口

    提前 关于抽象的描述并不完全代表具体的实现,但是具体实现不会脱离抽象描述 关于这个接口,官方给的描述太多太多,不用看的太仔细,随意看看就好 集合层次结构中的根接口. 一个集合代表一组对象,称为它的元素 ...

  5. DotText源码阅读(2)-工程、数据库表结构

    首先,来看整个工程结构,在此间单列出来,其中很多是初次阅读写下的,可能有些理解不正确,需要注意: 一.解决方案的组成项目 a)        Dottext.Web 引用了: ActiproSoftw ...

  6. [导入]DotText源码阅读(2)-工程、数据库表结构

    包括了工程结构说明和数据库表格说明,大致了解以上可以帮助我们后面的阅读理解. 文章来源:http://blog.csdn.net/shanhe/archive/2006/05/04/707482.as ...

  7. php微框架 flight源码阅读

    Flight(https://github.com/mikecao/fl... 是一个可扩展的PHP微框架,快速.简单,能够快速轻松地构建RESTful web应用程序,在github上有2k sta ...

  8. CI框架源码阅读笔记4 引导文件CodeIgniter.php

    到了这里,终于进入CI框架的核心了.既然是"引导"文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http:// ...

  9. Rpc框架dubbo-client(v2.6.3) 源码阅读(二)

    接上一篇 dubbo-server 之后,再来看一下 dubbo-client 是如何工作的. dubbo提供者服务示例, 其结构是这样的! dubbo://192.168.11.6:20880/co ...

  10. centos下将vim配置为强大的源码阅读器

    每日杂事缠身,让自己在不断得烦扰之后终于有了自己的清静时光来熟悉一下我的工具,每次熟悉源码都需要先在windows端改好,拖到linux端,再编译.出现问题,还得重新回到windows端,这个过程太耗 ...

最新文章

  1. “大龄”码农的“中年危机”:35岁之后,该如何应对?
  2. LCD控制器与帧率、刷新率的关系分析
  3. 爬虫的步骤解析内容xpath介绍_爬虫入门到精通-网页的解析(xpath)
  4. eclipse发布web项目到tomcat服务器
  5. php可以支持代码重用技术的命令,Linux下的编程 PHP高级技巧全放送(一)
  6. 训练日志 2018.12.26
  7. Go并发编程里的数据竞争以及解决之道
  8. 55 - 算法 -动态规划 -数塔问题 感觉都是数组建模 递推方法规则
  9. 坚守本心,你公司的OA解决了以下问题吗?
  10. 素数表的获取 O(nloglogn)复杂
  11. centos java进程号_centos中分析java占用大量CPU资源的原因
  12. CentOS 6系统FreeSwitch和RTMP服务 安装及演示(二)
  13. Android Toast 总结
  14. 宏脉系统显示连接服务器失败,宏脉系统使用手册大全.doc
  15. STM8L152C6T6+IAP详解,包教包会
  16. 射频(RF)和微波电路发展简史(一)
  17. emwin emf格式视频生成环境搭建
  18. 主机甲和乙已建立了 TCP 连接,甲始终以 MSS=1KB 大小的段发送数据,并一直有数据 发送;乙每收到一个数据段都会发出一个接收窗口为 10KB 的确认段。若甲在 t 时刻发生超 时时拥塞窗口为
  19. Confusing Problem
  20. ECSHOP漏洞集:http://sebug.net/appdir/ECSHOP

热门文章

  1. getParameter和getAttribute区别(超详细分析)
  2. 批量输出lib文件名(PCL或者opencv等环境配置)
  3. JAVA连接数据库 遍历集合数组!!!
  4. java 数据类型 date_Java 数据类型之 Date 数据类型
  5. 微信小程序云开发教程-微信小程序的API入门-获取用户身份信息系列API
  6. excel转word后表格超出页面_妙招!Word和Execl“联姻”实现数据高效处理!
  7. java lambda_Java 8 Lambda 表达式 ( 中 )- 外部参数
  8. oracle虚拟件不活动,BOM 中的虚拟件
  9. long 雪花算法_深入分析mysql为什么不推荐使用uuid或者雪花id作为主键
  10. map 和 hash_map 的使用方法