您的位置:首页 > 其它

自定义配置数据处理

2006-03-01 15:30 239 查看
典型案例分析:MSDN UrlRewrite项目
分析内容:URL重写的配置数据处理

配置数据的最终结果
<RewriterConfig>
<Rules>
<RewriteRule>
<LookFor>原始URL</LookFor>
<SendTo>新URL</SendTo>
</RewriteRule>
</Rules>
</RewriterConfig>

要处理的节次是RewriterConfig节次,因此,要为这个节次在Web.Config文件中定义一个Section,指明所使用的程序集的类名
<section name="RewriterConfig" type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" />

RewriterConfigSerializerSectionHandler就是用于从配置文件中读取配置节次并最终形成配置对象的类了,这里听上去有点绕,实际上,ASP.NET自定义配置数据的读取过程是一个XML数据序列化和反序列化的过程,不过,一般情况下,我们只考虑反序列化的情形就行了,你可以把上面的配置节次数据,看到一个XML对象在序列化后的结果,那么,RewriterConfigSerializerSectionHandler的作用就是要读取这个节次的XML内容,并且反序列化为一个对象.
问题是?这个对象是什么东东?它又有什么内容呢?
我们姑且叫这个对象叫做配置对象吧,这是一个较为普遍的叫法
这个配置对象应该包含一个Rules集合,这个集合中有若干个Rule元素
那Rule又是什么呢?rule是一个元数据类(可以这样说吗?就是最底层的了),它有两个属性,一个叫LookFor,代表原始的URL,一个叫SendTo代表新URL
经过我们的反向还原后,我们由上面的配置数据,清理出以下对象来,我们按朝依存关系自低往高罗列:
这是最基本的RULE对象的伪码
Public class rule
{
Public string LookFor{…};
Public string SendTo {…}
}
若干个Rule 对象集合在一起,构成一个Rules集合对象
Public class RuleCollection:CollectoinBase
{
Public virtual void Add{…}//加入一个规则到集合
Public Rule this[int index] {}//定义索引器
}
处理集合的过程相对简单,因为.NET为我们构造集合类提供了基类CollectionBase
接下来,这个规则集合得属于一个配置对象吧,因此,我们要定义一个rewriteCOnfig对象
Public class RewriteConfig()
{
Public rulecollection Rules {….};
}
配置对象也很简单,就只有一个Rules属性,它是一个RuleCollection对象

三个对象构成了一个树状层次,就像前头的那个配置节次一样,简单而明了
这里需要注意XML序列化的一个规则,XML在序列化普通对象,如Rule时,会将每个属性序列为化一个XML元素,而类名则是父元素,而对于集合,则是序列化集合中每一个对象,因此,假如更改了Rule对象的LookFor属性,那么,你最终的WEB.CONFIG文件中对应的LookFor元素名也要改变,相同的道理适用于其他对象
这点倒也不难理解,不过要小心就是了.而且,假如你的对象的属性名称改变,而程序集.DLL.CONFIG文件中的对应元素未改变,则有可能你在使用NUNIT测试的时候,NUNIT会提示"无法加载Nunit.Core….."之类的,其实这个跟NUNIT没有关系的,我就遇到过,卡了很久,以为是NUNIT的问题,后来查到是更名后类名,属性名与CONFIG文件中的元素名不一致的原因

另外,三个类都必须添加属性Serializable表时是可序列化的
最后,对于顶级的RewriteConfig对象,缺省情况下,会以其类名作为XML标记名进行序列化,当然,如果你需要自行定义其生成和解析时使用的XML标记名,请使用XmlRoot("标记名")属性进行标识
另外,作为配置对象,由于是顶级对象,因此,特别需要记住的是配置文件中的标记名,ConfigurationSettings.GetConfig(标记名)一定要和XmlRoot中指定的标记名一致,否则,读取配置数据一定会出错

最后,配置对象,以及配置对象所需的各个辅助对象都备齐了,剩下的,就是覆写IConfigurationSectionHandler的方法Create(object parent,object configcontext,XmlNode section)
这里要注意的是这个Create方法的意思是,由给定的ConfigContext上下文,和指定的XmlNode对象建立一个客户的自定义配置对象,实际上就是反序列化的过程
Create方法会建立一个配置对象
Create建立配置对象的方法是建立一个XmlSerailizer对象,使用Desirialize方法反序列化即可,通常是这样
public object Create(object parent, object configContext, XmlNode section)
{
XmlSerializer Xs=new XmlSerializer(typeof(UrlRewriteRuleConfiguration));
return(Xs.Deserialize(new XmlNodeReader(section)));
}

那么,我们在代码中,该如何获取这个配置对象呢?
ConfigurationSettings类是专门负责从config文件中读取配置数据并实例为配置对象的,
ConfigurationSettings.GetConfig("配置节名")就是具体负责的静态方法了
首先,你在代码中调用此方法,然后,ConfigurationSetting对象根据传递的配置节名,读取该节点内容,生成一个XMLNODE对象,然后,再读取Section定义,找到用于处理该配置节名配置实例化的SectionHandler,然后,传递XMLNODE对象给该SectionHandler类,并调用该类的Create方法,Create方法生成配置对象并返回,整个过程就结束了
实际上,ASP.NET的这种配置方法扩展性相当高,允许你定义配置对象,以及配置对象的处理对象,只要你覆写CREATE方法并返回配置对象,就可以在代码中,用统一的ConfigurationSettings.GetConfig取得各式各样的配置对象,实在是高明

另外方面,Asp.net也预置了一些供客户使用的SectionHandler
NameValueSectionHandler 返回一个NameValueCollection对象
DictionarySectionHandler 返回dictionary对象
SingleTagSectionHandler 返回dictionary对象
IgonreSectionhandler 处理外部配置数据

还有,为了方便,ASP.NET还提供了appSettings节次,并且,已经实现了对其的访问,直接通过
ConfigurationSettings.appSettings数组就可以访问其中数据

.NET的配置文件扩展性强,也较容易扩展,是值得借鉴的处理方式
另外,整个.NET配置文件,所有节次,像appSettings,还有<error,全部都用以上方式实现,灵活而强大
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: