All articles| All Pictures| All Softwares| All Video| Go home page| Write articles| Upload pictures

Reading number is top 10 articles
经典文萃:Ajax技术的安全问题不容忽视_.net资料_编程技术
FCKeditor(asp.net)使用方法_[Asp.Net教程]
php基础编程代码四则_[PHP教程]
数据库死锁导致网站站点访问不了之解决方案_[SQL,Server教程]
VBScript教程,第四课,VBScript变量_JavaScript技术_编程技术
asp.net回车键执行相应按钮事件的代码_[Asp.Net教程]
如何授予对存储过程的权限_[SQL Server教程]
php用session做客户验证时的注意事项_[PHP教程]
ASP.NET实现文件的在线压缩和解压缩_[Asp.Net教程]
全面接触SQL语法(1)_mssql学习_编程技术
Reading number is top 10 pictures
Sora aoi possession of boudoir2
More attractive than sora aoi1
Sell the barbecue as says father du breul5
色狗系列
中国的阶级现状
美女和狗狗2
什么叫国家
大人物的礼物
鸡也看毛片
Beautiful Japanese beauty(漂亮的日本美女)
Download software ranking
Be there or be square
塘西风月痕
在线棋牌游戏3.05版
Unix video tutorial15
中国结婚习俗实录
1400篇各类破解文章
仙剑奇侠传98版歌曲
功夫熊猫2(下集)
Ashlynn Video2
Tram sex maniac 2 (H) rar bag16
delv published in(发表于) 2014/1/10 6:23:15 Edit(编辑)
.NET,2.0,中的自定义配置处理_[Asp.Net教程]

.NET,2.0,中的自定义配置处理_[Asp.Net教程]

.NET 2.0 中的自定义配置处理_[Asp.Net教程]

引言

  现代软件开发中,各种技术、技巧越来越依赖配置,譬如客户端对用户体验的个性化设置、系统的各种运行时参数设置、可插拔的插件机制、基于配置的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 (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/"")。

  节点集合

  创建派生自 ConfigurationElementCollection 的类,在派生类中必须重写(override)的抽象方法:


protected abstract ConfigurationElement CreateNewElement()

  在从配置文件加载集合时,会调用该方法以创建各个元素。重写该方法以创建特定类型的自定义 ConfigurationElement 对象。


protected abstract object GetElementKey(ConfigurationElement element)

  在派生类中重写时获取指定配置元素的键值。

  对于非默认的节点集合类,还必须重写 CollectionType 和 ElementName 只读属性的getter,其代码可能如下:


protected override string ElementName
{
 get
 {
  return "dataProvider"; //"dataProvider" replace with your elementName in collection.
 }
}

public override ConfigurationElementCollectionType CollectionType
{
 get
 {
  return ConfigurationElementCollectionType.BasicMap;
 }
}

  可以重写 ThrowOnDuplicate 只读属性的getter,以指示当向 ConfigurationElementCollection 添加重复的 ConfigurationElement 是否会导致引发异常。默认情况,只有当该元素的 CollectionType 值为 AddRemoveClearMap 或 AddRemoveClearMapAlternate 时才会引发异常,如果希望非默认节点集合不接受重复项(通常如此),那么就必须重写该属性的getter,始终返回真(true)。

  请注意,键和值都相同的元素不会被视为重复元素,而是接受此类元素且不出现提示,只有键相同而值不同的元素才被视为是重复元素。原因是这些元素不会进行竞争。但是,无法添加键相同而值不同的元素,因为无法从逻辑上确定哪个竞争值有效。

  索引器的设计模式

  通常需要定义索引器的两个重载(overloads),一个接受整型数下标的可读写的索引器;一个是接受字符串键值的只读索引器。


public DataProviderElement this[int index]
{
 get
 {
  return (DataProviderElement)BaseGet(index);
 }
 set
 {
  if(BaseGet(index) != null)
   BaseRemoveAt(index);

  BaseAdd(index, value);
 }
}

public new DataProviderElement this[string name]
{
 get
 {
  return (DataProviderElement)BaseGet(name);
 }
}

  其他事项

  通常还需要公开一些对集合操作的方法,大致如下:


public int IndexOf(DataProviderElement value)
{
 return BaseIndexOf(value);
}

public void Add(DataProviderElement value)
{
 BaseAdd(value);
}

public void Remove(DataProviderElement value)
{
 if(BaseIndexOf(value) >= 0)
  BaseRemove(value.Name);
}

public void Remove(string name)
{
 BaseRemove(name);
}

public void RemoveAt(int index)
{
 BaseRemoveAt(index);
}

public void Clear()
{
 BaseClear();
}

  总结

  这只是我想要撰写的有关 .NET 2.0 中的基础技术篇文章中的第一篇。在这篇文章中,我介绍了有关配置方面的一些基本概念,并阐述了在 .NET 2.0 中如何定制你自己的配置处理程序,以及这过程中需要注意的一些细节问题。您已经看到,通过对 .NET 2.0 中提供的基础架构的扩展,我们可以很容易完成特性化的配置定制。
作者:钟峰 来源:中汉软件有限公司





添加到del.icio.us 添加到新浪ViVi 添加到百度搜藏 添加到POCO网摘 添加到天天网摘365Key 添加到和讯网摘 添加到天极网摘 添加到黑米书签 添加到QQ书签 添加到雅虎收藏 添加到奇客发现 diigo it 添加到饭否 添加到飞豆订阅 添加到抓虾收藏 添加到鲜果订阅 digg it 貼到funP 添加到有道阅读 Live Favorites 添加到Newsvine 打印本页 用Email发送本页 在Facebook上分享


Disclaimer Privacy Policy About us Site Map

If you have any requirements, please contact webmaster。(如果有什么要求,请联系站长)
Copyright ©2011-
uuhomepage.com, Inc. All rights reserved.