日期:2010-11-03  浏览次数:20462 次

  引言

  现代软件开发中,各种技术、技巧越来越依赖配置,譬如客户端对用户体验的个性化设置、系统的各种运行时参数设置、可插拔的插件机制、基于配置的IoC架构模式等。配置方式也从最初的二进制存储格式逐步过度到INI文本格式直至今时所广泛使用的Xml格式。使用Xml格式进行配置,大大提高了对设置数据的表现能力,但是在 .NET 1.x 中对Xml配置的操控还有诸多不便,尤其是对Xml配置的存储同步机制很不完善,而从 .NET 2.0 开始,框架提供了更丰富和易于操控使用的机制。

  .NET 中的配置文件(Xml)必须以“<configuration>”为根节点,配置文件分为两大部分:配置声明区和数据设置区。

  配置声明区:位于<configuration><configSections>内,通过<section>节点进行声明定义。

  数据设置区:位于<configuration>根节点内除<configSections>以外的任意节点。

  数据设置区可以是用户定义的任意结构层次,但是其“根节点”必须预先在设置声明区定义,运行时会进行有效性检测,一旦发现没有声明的配置节点则会产生一个运行时配置异常。

  范例配置文件

<configuration>
<configSections>
<section name="dataSystems" type="SWSystem.Data.Configuration.DataSystemsSection, SWSystem.Data" />
</configSections>

<dataSystems>
<dataSystem name="iMRP" currentProvider="SQLProvider">
<dataProvider name="MSSqlProvider" type="SWSystem.Data.Providers.SQLDataProvider" dataFile="D:\Zongsoft\Develop 2005\SWSystem.Data\Services\SWDataEngine.xml" connectionString="UID=sa;PWD=;Initial Catalog=iMRP;Data Source=127.0.0.1" />
<dataProvider name="PostgreSqlProvider" type="SWSystem.Data.Providers.PostgreDataProvider" dataFile="D:\Zongsoft\Develop 2005\SWSystem.Data\Services\SWDataEngine.xml" connectionString="Server=127.0.0.1;Port=5432;User Id=postgres;Password=postgres;Database=iMRP;Encoding=UNICODE;" />

<dataModules>
<add name="StockModule" type="Zongsoft.Applications.iMRP.Business.StockModule, Zongsoft.Applications.iMRP.Business" />
</dataModules>
</dataSystem>
</dataSystems>
</configuration>


  概述

  在.NET 2.0中实现自定义配置,可以使用编程或声明性(属性化)代码编写模型创建自定义配置节。

  编程模型。此模型要求为每个节属性 (Attribute) 创建一个用于获取和/或设置其值的属性 (Property),并将其添加到基础 ConfigurationElement 基类的内部属性 (Property) 包中。

  声明模型。这种比较简单的模型也称为属性 (Attribute) 化模型,允许您通过使用属性 (Property) 来定义节属性 (Attribute),并使用属性 (Attribute) 对其进行修饰。

  配置文件中的元素称为 基本XML元素 或 节。基本元素只是具有相关属性(如果有)的简单 XML 标记。节最简单的形式与基本元素一致。而复杂的节可以包括一个或多个基本元素、元素的集合以及其他节。

  ConfigurationProperty 类表示配置节点中的特性(Attribute)或它的子元素,我们要做的就是通过 ConfigurationProperty 类将配置实体类中的属性(Property)映射到对应的节点特性(Attribute)。

  配置声明

  要在配置文件中使用自定义的配置数据,必须在声明区通过<section>节点对自定义配置节处理程序进行声明,该节点有两个必需属性:name 和 type。

  name 属性:指定与 type 属性中指定的配置节处理程序关联的配置节或元素的名称。这是该元素在配置文件的设置区中使用的名称。

  type 属性:指定用来处理 name 属性所指定的设置节的处理程序。使用如下格式:
type="ConfigurationSectionHandlerClass, AssemblyFileName, Version, Culture, PublicKeyToken"
如果对处理程序的版本没要求,或者其为无区域和强签名的程序集,则可以省略后面的三项,否则必须严格匹配版本。注意:程序集文件名不要带其扩展文件名(通常为.dll)。

  范例配置文件中的配置声明定义如: <section name="dataSystems"  type="SWSystem.Data.Configuration.DataSystemsSection, SWSystem.Data" /> 则表示数据设置区中的<dataSystems>节点由 SWSystem.Data.Configuration.DataSystemsSection 类进行处理,并且该类位于 SWSystem.Data 程序集中。

  在 .NET 1.x 中要实现自定义的配置处理程序类,其必须实现 IConfigurationSectionHandler 接口,现在 .NET 2.0 中只需要将你的处理程序类继承自 ConfigurationSection 类即可。其处理步骤大致如下:

  首先定义并创建一个 ConfigurationPropertyCollection 类的实例,用以保存配置节点的特性(Attribute)以及它的所有子元素映射,当然你也可以使用 ConfigurationElement 基类中的 Properties 属性。

  然后创建 ConfigurationProperty 类以映射到对应的节点特性(Attribute)或子元素。

  在类型构造函数或实例构造函数中,将创建的 ConfigurationProperty 类实例加入到已创建好的 ConfigurationPropertyCollection 集合中。

  最终,我们的范例配置处理程序类看起来可能是这样(如果你使用声明模式则代码看起来没有这么麻烦,这些配置属性类将由框架运行时帮你反射生成,正因为如此,所以它的运行时效率要差些。):

public class DataSystemsSection : ConfigurationSection
{
 private static readonly ConfigurationProperty _dataSystems = new ConfigurationProperty(null, typeof(DataSystemElementCollection), null, ConfigurationPropertyOptions.IsDefaultCollection);
 private static ConfigurationPropertyCollection _properties = new ConfigurationPropertyCollection();

 static DataSystemsSection()
 {
  _properties.Add(_dataSystems);
 }

 public DataSystemElementCollection DataSystems
 {
  get
  {
   return (D