C#讀取自定義的config


今天說下C#讀寫自定義config文件的各種方法。由於這類文章已經很多,但是大多數人舉例子都是默認的在app.confg或者web.config進行讀寫,而不是一般的XML文件,我主要寫的是一般的Xml文件,不是默認路徑下的app.config.

通常,我們在.NET開發過程中,會接觸二種類型的配置文件:config文件,xml文件。今天我主要演示如何創建自己的自定義的配置節點,而不是介紹如何使用appSetting.

首先來看下配置節點。

 

 1 <?xml version="1.0" ?> 
 2 <configuration> 
 3 <configSections> 
 4 <section name="MySection1" type="ConfigApplicationDemo.MySection1, ConfigApplication" /> 
 5 <section name="MySection2" type="ConfigApplicationDemo.MySection2, ConfigApplication" /> 
 6 <section name="MySection3" type="ConfigApplicationDemo.MySection3, ConfigApplication" /> 
 7 <section name="MySection4" type="ConfigApplicationDemo.MySection4, ConfigApplication" />
 8  </configSections> 
 9 <MySection1 name="Halia" url="http://www.cnblogs.com/halia/">
10 </MySection1> 
11 <MySection2> 
12 <users username="halia" password="test2012"></users> </MySection2> 
13 <MySection3> 
14 <add key="aa" value="11111"></add>
15  <add key="bb" value="22222"></add>
16  <add key="cc" value="33333"></add> 
17 </MySection3> 
18 <MySection4> 
19  <add name="aa" id="11111" role="test"></add>
20  <add name="bb" id="22222" role="key"></add>
21  <add name="cc" id="33333" role="rest"></add> 
22 </MySection4> 
23  </configuration>

 

 

這里大家可以看到我定義了四種不同的section,其中前兩種介紹的人很多,這里不多贅述,先看看第三種。

 

<MySection3> 
<add key="aa" value="11111"></add>
<add key="bb" value="22222"></add>
<add key="cc" value="33333"></add> 
</MySection3> 

這個配置具有一系列數據,這時候就要用到collection,代碼如下:

public class MySection3 : ConfigurationSection    // 所有配置節點都要選擇這個基類
{    
private static readonly ConfigurationProperty s_property = new ConfigurationProperty(string.Empty, typeof(TheKeyValueCollection), null, ConfigurationPropertyOptions.IsDefaultCollection); [ConfigurationProperty("", Options = ConfigurationPropertyOptions.IsDefaultCollection)] public TheKeyValueCollection KeyValues
{
  get {
      return (TheKeyValueCollection)base[s_property];
     } }


[ConfigurationCollection(
typeof(TheKeyValue))]
public class TheKeyValueCollection: ConfigurationElementCollection // 自定義一個集合 { new public TheKeyValuethis[string name]
  { get {
      
return (TheKeyValue)base.BaseGet(name);
  }
}
// 下面二個方法中抽象類中必須要實現的。 protected override ConfigurationElement CreateNewElement()
  {
    return new TheKeyValue();
  }
protected override object GetElementKey
  (
    ConfigurationElement element)
  {
return ((TheKeyValue)element).Key;
  }
}


public class TheKeyValue : ConfigurationElement // 集合中的每個元素 {
  [ConfigurationProperty("key", IsRequired = true)]
  public string Key
  {
get { return this["key"].ToString(); } set { this["key"] = value; }
  }
[ConfigurationProperty(
"value", IsRequired = true)]
  public string Value {
    get { return this["value"].ToString(); } set { this["value"] = value; } }
  }
}

上面的三個class做了三件事:
1. 為每個集合中的參數項創建一個從ConfigurationElement繼承的派生類。
2. 為集合創建一個從ConfigurationElementCollection繼承的集合類,具體在實現時主要就是調用基類的方法。
3. 在創建ConfigurationSection的繼承類時,創建一個表示集合的屬性就可以了,注意[ConfigurationProperty]的各參數。

然后就是讀取config中的值,在讀取自定節點時,我們需要調用ConfigurationManager.GetSection()得到配置節點,並轉換成我們定義的配置節點類,然后就可以按照強類型的方式來訪問了。

                if (!string.IsNullOrEmpty(ConfigFile))
//這里的ConfigFile是你要讀取的Xml文件的路徑,如果為空,則使用默認的app.config文件
{
var fileMap = new ExeConfigurationFileMap() { ExeConfigFilename = ConfigFile }; var config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); MySection3 configSection = (MySection3 )config.GetSection("MySection3"); } else { //Get the default config app.config MySection3 configSection = (MySection3 )ConfigurationManager.GetSection("MySection3"); }

var values = from kv in configSection.KeyValues.Cast<TheKeyValue>()
                         select new
            { key=kv.Key, val=kv.Value)};

 我們在來看下section4的配置:

<MySection4> 
<add name="aa" id="11111" role="test"></add>
<add name="bb" id="22222" role="key"></add>
<add name="cc" id="33333" role="rest"></add> 
</MySection4> 

這個關於Collection的寫法和第三個差不多,不同之處在於屬性的定義是不同的。

public class TheKeyValue : ConfigurationElement    // 集合中的每個元素
{    
  [ConfigurationProperty("name", IsRequired = true)]    
  public string Name
  {
        get { return this["name"].ToString(); }
        set { this["name"] = value; }    
  }

    [ConfigurationProperty("id", IsRequired = true)]    
  public string Id
    {        
    get { return this["id"].ToString(); }
        set { this["id"] = value; }    }
  }

    [ConfigurationProperty("role", IsRequired = true)]    
  public string Role
    {        
    get { return this["role"].ToString(); }
        set { this["role"] = value; }    }
  }
}

然后是獲取相應的值:

 if (!string.IsNullOrEmpty(ConfigFile))
//這里的ConfigFile是你要讀取的Xml文件的路徑,如果為空,則使用默認的app.config文件
                {

                    var fileMap = new ExeConfigurationFileMap() { ExeConfigFilename = ConfigFile };
                    var config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
                   MySection4 configSection = (MySection4 )config.GetSection("MySection4");
                }
                else
                {
                    //Get the default config app.config
                    MySection4  configSection = (MySection4 )ConfigurationManager.GetSection("MySection4");
                }

             var values = from v in configSection.KeyValues.Cast<TheKeyValue>()
                         select new
            { name=v.Name, id=v.Id,role=v.Role)};

上面就是關於自定義section的一些分享,這里還要說一下section里面的type
<section name="MySection1" type="ConfigApplicationDemo.MySection1, ConfigApplication" />

關於這個type的定義,逗號前面ConfigApplicationDemo.MySection1, 需要對應你的namespace和你的section類的名字,逗號后面需要對應的是你編譯出來的dll的名字,很多情況下namespace和dll名字是一樣的,但是出現不一樣的情況一定要注意,不然type定義不好,或版本不對,會報錯,錯誤如下,程序會告訴你找不到指定的file或者section。

An error occurred creating the configuration section handler for XXX: Could not load type..

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM