国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

.NET 2.0 中的自定義配置處理

2024-07-10 13:09:46
字體:
來源:轉載
供稿:網友
  引言

  現代軟件開發中,各種技術、技巧越來越依賴配置,譬如客戶端對用戶體驗的個性化設置、系統的各種運行時參數設置、可插拔的插件機制、基于配置的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 中提供的基礎架構的擴展,我們可以很容易完成特性化的配置定制。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 平阳县| 丰都县| 新巴尔虎右旗| 清苑县| 东阳市| 金沙县| 盐城市| 康定县| 太原市| 天峨县| 怀集县| 双桥区| 宁南县| 北京市| 黔西县| 南平市| 五原县| 贡嘎县| 泸州市| 松滋市| 大宁县| 通海县| 堆龙德庆县| 丹江口市| 黑山县| 浦江县| 郯城县| 海口市| 红原县| 甘肃省| 特克斯县| 乌拉特前旗| 洮南市| 革吉县| 桐城市| 吉隆县| 屏东市| 泰宁县| 伊川县| 沅江市| 万山特区|