科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件.NET 2.0 中的自定义配置处理

.NET 2.0 中的自定义配置处理

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

现代软件开发中,各种技术、技巧越来越依赖配置

作者:钟峰 来源:中汉软件有限公司 2007年11月3日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
 配置声明

  要在配置文件中使用自定义的配置数据,必须在声明区通过<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 (DataSystemElementCollection)base[_dataSystems];
  }
 }

 protected override ConfigurationPropertyCollection Properties
 {
  get
  {
   return _properties;
  }
 }
}

  节点映射/配置实体

  为所有的配置节点创建对应的配置实体类,该类中的属性(Property)对应节点中的特性(Attribute)和子元素(集合)。其编写步骤和开发方式与处理程序类似,只是这时我们的基类变成了 ConfigurationElement。

public class DataSystemElement : ConfigurationElement
{
 private static readonly ConfigurationProperty _name = new ConfigurationProperty("name", typeof(string), null, null, new StringValidator(1), ConfigurationPropertyOptions.IsKey | ConfigurationPropertyOptions.IsRequired);
 private static readonly ConfigurationProperty _currentProvider = new ConfigurationProperty("currentProvider", typeof(string), string.Empty, ConfigurationPropertyOptions.IsRequired);
 private static readonly ConfigurationProperty _dataModules = new ConfigurationProperty("dataModules", typeof(DataModuleElementCollection), null, ConfigurationPropertyOptions.None);
 private static readonly ConfigurationProperty _dataProviders = new ConfigurationProperty(null, typeof(DataProviderElementCollection), null, ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsDefaultCollection);

 private static ConfigurationPropertyCollection _properties = new ConfigurationPropertyCollection();

 #region 类型构造函数
 static DataSystemElement()
 {
  _properties.Add(_name);
  _properties.Add(_currentProvider);
  _properties.Add(_dataProviders);
  _properties.Add(_dataModules);
 }
 #endregion

 #region 构造函数
 public DataSystemElement()
 {}

 public DataSystemElement(string name)
 {
  this.Name = name;
 }

 public DataSystemElement(string name, string currentProvider)
 {
  this.Name = name;
  this.CurrentProviderName = currentProvider;
 }
 #endregion

 #region 公共属性
 public string Name
 {
  get
  {
   return (string)base[_name];
  }
  set
  {
   base[_name] = value;
  }
 }

 public String CurrentProviderName
 {
  get
  {
   return (string)this[_currentProvider];
  }
  set
  {
   this[_currentProvider] = value;
  }
 }

 public DataModuleElementCollection DataModules
 {
  get
  {
   return (DataModuleElementCollection)base[_dataModules];
  }
 }

 public DataProviderElementCollection DataProviders
 {
  get
  {
   return (DataProviderElementCollection)base[_dataProviders];
  }
 }
 #endregion
}

  需要注意的是,<dataProvider> 和 <dataModules> 子元素处理方式的差异。

  <dataModules> 是个嵌套的集合节点,它下面有标准的 <add>, <remove>, <clear> 子元素,且 <dataModules> 元素不能在同一个 <dataSystem> 节点下出现多次。

  <dataProvider> 是 <dataSystem> 节点下的直接子节点集合,<dataProvider> 是可以在同一个父节点下出现多次的集合项节点,故需要对其映射的 ConfigurationProperty 类构造函数中的 options 参数包含 ConfigurationPropertyOptions.IsDefaultCollection 枚举项(它指示.NET框架构造一个嵌套节),另外,不能指定它对应的配置节点的名字,即必须保持构造函数中 name 参数的值为空引用([C#]null/[VB.net]Nothing)或空字符串(String.Empty/"")。
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章