在web.config和app.config文件中增加自定義配置節(jié)點(diǎn)的方法
有經(jīng)驗(yàn)的開(kāi)發(fā)人員都知道在開(kāi)發(fā).NET應(yīng)用時(shí)可以利用配置文件保存一些常用并且有可能變化的信息,例如日志文件的保存路徑、數(shù)據(jù)庫(kù)連接信息等等,這樣即使生產(chǎn)環(huán)境中的參數(shù)信息與開(kāi)發(fā)環(huán)境不一致也只需要更改配置文件而不用改動(dòng)源代碼再重新編譯,極其方便。并且我們一般還約定,在<appSettings>節(jié)點(diǎn)保存應(yīng)用程序的配置信息,在<connectionStrings>中保存數(shù)據(jù)庫(kù)連接字符串信息。
上面的這些方法和約定足以讓我們?cè)诖蟛糠珠_(kāi)發(fā)中獲得方便,但是在有些情況下有些配置信息可以按組分類(lèi)存放,如果采用上面的方法不僅不直觀(guān),而且讀取起來(lái)也不是太方便,幸好在.NET里就提供了這樣的方法。如果有使用過(guò)Log4Net或者Enyim.Caching的朋友,肯定對(duì)下面的配置不會(huì)陌生:
<sectionGroup name="enyim.com"><section name="memcached"
type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" /></sectionGroup>
或:
<configSections><section name="log4net" type="System.Configuration.IgnoreSectionHandler"/></configSections>
在出現(xiàn)上面配置的配置文件中,我們就會(huì)找到名稱(chēng)為"enyim.com"或者"log4net"的節(jié)點(diǎn),盡管它們本不屬于config文件的默認(rèn)節(jié)點(diǎn),但是通過(guò)上面的配置之后程序運(yùn)行并不會(huì)報(bào)錯(cuò)。這樣一來(lái),相關(guān)配置信息也可以很好分類(lèi)保存起來(lái)。
在這里我演示一個(gè)簡(jiǎn)單的例子,這個(gè)例子來(lái)源于我的一個(gè)從2006年起就開(kāi)始開(kāi)發(fā)的自用軟件(因?yàn)闆](méi)有美化所以沒(méi)有免費(fèi)發(fā)布),在這個(gè)應(yīng)用程序的connfig文件中我增加了一些特有的配置,所以新增了一個(gè)自己的節(jié)點(diǎn),app.config文件內(nèi)容如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="SoftwareSettings" type="ImageAssistant.Configuration.SoftwareSettings, ImageAssistant" />
</configSections>
<SoftwareSettings>
<LoadSettings>
<add key="LoadBmp" value="true"/>
<add key="LoadJpg" value="true"/>
<add key="LoadGif" value="true"/>
<add key="LoadPng" value="false"/>
</LoadSettings>
<PathSettings SavePath="C:\ResizeImages\" SearchSubPath="true"/>
</SoftwareSettings>
<appSettings>
<add key="LoadBmp" value="true"/>
<add key="LoadJpg" value="true"/>
<add key="LoadGif" value="true"/>
<add key="LoadPng" value="false"/>
<add key="IncludeSubPath" value="true"/>
</appSettings>
</configuration>
在config文件中我們使用<section name="SoftwareSettings" type="ImageAssistant.Configuration.SoftwareSettings, ImageAssistant" />告訴應(yīng)用程序?qū)τ谂渲梦募械腟oftwareSettings節(jié)點(diǎn),其對(duì)應(yīng)的類(lèi)是ImageAssistant程序集中ImageAssistant.Configuration.SoftwareSettings類(lèi),并且在<SoftwareSettings>節(jié)點(diǎn)中我們還看到有<LoadSettings>節(jié)點(diǎn)和<PathSettings>節(jié)點(diǎn),其中<LoadSettings>是一個(gè)節(jié)點(diǎn)集合,還包含有多個(gè)子節(jié)點(diǎn),為了表示清楚這些關(guān)系我們需要添加四個(gè)類(lèi):SoftwareSettings、LoadSettingsCollection、LoadSettingsElement及PathSettingElement。為了發(fā)布方便,我將這四個(gè)類(lèi)的代碼放在一個(gè)物理文件中,代碼如下(注意添加對(duì)System.Configuration.dll的引用):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
namespace ImageAssistant.Configuration
{
public sealed class LoadSettingsCollection : ConfigurationElementCollection
{
private IDictionary<string, bool> settings;
protected override ConfigurationElement CreateNewElement()
{
return new LoadSettingsElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
LoadSettingsElement ep = (LoadSettingsElement)element;
return ep.Key;
}
protected override string ElementName
{
get
{
return base.ElementName;
}
}
public IDictionary<string, bool> Settings
{
get
{
if (settings == null)
{
settings = new Dictionary<string, bool>();
foreach (LoadSettingsElement e in this)
{
settings.Add(e.Key, e.Value);
}
}
return settings;
}
}
public bool this[string key]
{
get
{
bool isLoad = true;
if (settings.TryGetValue(key, out isLoad))
{
return isLoad;
}
else
{
throw new ArgumentException("沒(méi)有對(duì)'" + key + "'節(jié)點(diǎn)進(jìn)行配置。");
}
}
}
}
public class LoadSettingsElement : ConfigurationElement
{
[ConfigurationProperty("key", IsRequired = true)]
public string Key
{
get { return (string)base["key"]; }
set { base["key"] = value; }
}
[ConfigurationProperty("value", IsRequired = true)]
public bool Value
{
get { return (bool)base["value"]; }
set { base["value"] = value; }
}
}
public class PathSettingElement : ConfigurationElement
{
/// <summary>
///
/// </summary>
[ConfigurationProperty("SavePath", IsRequired = true)]
public string SavePath
{
get { return (string)base["SavePath"]; }
set { base["SavePath"] = value; }
}
/// <summary>
///
/// </summary>
[ConfigurationProperty("SearchSubPath", IsRequired = false, DefaultValue = true)]
public bool SearchSubPath
{
get { return (bool)base["SearchSubPath"]; }
set { base["SearchSubPath"] = value; }
}
}
/// <summary>
/// 對(duì)應(yīng)config文件中的
/// </summary>
public sealed class SoftwareSettings : ConfigurationSection
{
/// <summary>
/// 對(duì)應(yīng)SoftwareSettings節(jié)點(diǎn)下的LoadSettings子節(jié)點(diǎn)
/// </summary>
[ConfigurationProperty("LoadSettings", IsRequired = true)]
public LoadSettingsCollection LoadSettings
{
get { return (LoadSettingsCollection)base["LoadSettings"]; }
}
/// <summary>
/// 對(duì)應(yīng)SoftwareSettings節(jié)點(diǎn)下的PathSettings子節(jié)點(diǎn),非必須
/// </summary>
[ConfigurationProperty("PathSettings", IsRequired = false)]
public PathSettingElement PathSetting
{
get { return (PathSettingElement)base["PathSettings"]; }
set { base["PathSettings"] = value; }
}
}
}
在上面的代碼中可以看到ConfigurationProperty這個(gè)屬性,這是表示對(duì)應(yīng)的屬性在config文件中的屬性名,IsRequired表示是否是必須的屬性,還有DefaultValue表示屬性的默認(rèn)值。初次之外,我們還要注意以下關(guān)系:
SoftwareSettings:根節(jié)點(diǎn),繼承自ConfigurationSection。
LoadSettingsCollection:子節(jié)點(diǎn)集合,繼承自ConfigurationElementCollection。
LoadSettingsElement:子節(jié)點(diǎn),繼承自ConfigurationElement。
PathSettingElement:子節(jié)點(diǎn),繼承自ConfigurationElement。
編寫(xiě)了如下代碼之后,我們又該如何使用上面的類(lèi)呢?其實(shí)很簡(jiǎn)單,如下:
class Program
{
static void Main(string[] args)
{
SoftwareSettings softSettings = ConfigurationManager.GetSection("SoftwareSettings") as SoftwareSettings;
foreach (string key in softSettings.LoadSettings.Settings.Keys)
{
Console.WriteLine("{0}={1}", key, softSettings.LoadSettings[key]);
}
Console.WriteLine("SavePath={0},SearchSubPath={1}", softSettings.PathSetting.SavePath, softSettings.PathSetting.SearchSubPath);
Console.ReadLine();
}
}
這個(gè)程序的運(yùn)行結(jié)果如下:
LoadBmp=True
LoadJpg=True
LoadGif=True
LoadPng=False
SavePath=C:/ResizeImages/,SearchSubPath=True
總結(jié):在上面的config文件中通過(guò)<appSettings>也達(dá)到了類(lèi)似的效果,但是通過(guò)自定義節(jié)點(diǎn)我們可以方便地讀取相關(guān)的應(yīng)用程序配置,同時(shí)也便于維護(hù)。如果在開(kāi)發(fā)過(guò)程中遇到本文中類(lèi)似的情況,不妨采取本文所述的方式。
相關(guān)文章
C#實(shí)現(xiàn)優(yōu)先隊(duì)列和堆排序
本文詳細(xì)講解了C#實(shí)現(xiàn)優(yōu)先隊(duì)列和堆排序的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04c# WinForm制作圖片編輯工具(圖像拖動(dòng)、縮放、旋轉(zhuǎn)、摳圖)
這篇文章主要介紹了c# WinForm制作圖片編輯工具(可實(shí)現(xiàn)圖像拖動(dòng)、縮放、旋轉(zhuǎn)、摳圖),幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下2021-03-03WinForm實(shí)現(xiàn)為T(mén)extBox設(shè)置水印文字功能
這篇文章主要介紹了WinForm實(shí)現(xiàn)為T(mén)extBox設(shè)置水印文字功能,很實(shí)用的一個(gè)技巧,需要的朋友可以參考下2014-08-08C#難點(diǎn)逐個(gè)擊破(2):out返回參數(shù)
之前提到ref是將原方法中的參數(shù)影響的結(jié)果返回到調(diào)用它的方法中,out與ref類(lèi)似,相比之下,ref傳遞參數(shù)的地址,out是返回值。2010-02-02C#使用Clipboard類(lèi)實(shí)現(xiàn)剪貼板功能
這篇文章介紹了C#使用Clipboard類(lèi)實(shí)現(xiàn)剪貼板功能的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06C#實(shí)現(xiàn)ComboBox自動(dòng)匹配字符
本文介紹C#如何實(shí)現(xiàn)ComboBox自動(dòng)匹配字符1.采用CustomSource當(dāng)做提示集合2. 直接使用下拉列表中的項(xiàng)作為匹配的集合,需要了解的朋友可以參考下2012-12-12C#中String StringBuilder StringBuffer類(lèi)的用法
這篇文章給大家簡(jiǎn)單介紹下C#中String StringBuilder StringBuffer三個(gè)類(lèi)的用法,需要的的朋友參考下吧2017-05-05