<configuration>//根节点
<configSections> //配置节声明区域
<section name="MySection" type="System.Configuration.DictionarySectionHandler"/>//配置节声明(无父组声明)
<sectionGroup name="MySectionGroup">//定义配置节组
<section name="MyFirstSection" type="System.Configuration.SingleTagSectionHandler"/>//配置节组中的配置节声明1
<section name="MySecondSection" type="System.Configuration.NameValueSectionHandler"/>//配置节组中的配置节声明2
</sectionGroup>
</configSections>
//配置节设置区域开始
<MySectionGroup>
<MyFirstSection MyFirstSection="First"/>
<MySecondSection>
<add key="Second" value="Second Section"/>
</MySecondSection>
</MySectionGroup>
<MySection>
<add key="Top" value="Top Section"/>
</MySection>
<pre name="code" class="html"> //配置节设置区域结束
</configuration>
配置节按类型分系统默认声明(存储键值对)和自定义配置
一:系统默认
1.1.声明
系统默认声明类型包括三种:
①:System.Configuration.SingleTagSectionHandler (自定义配置设置键值属性,返回 System.Collections.Hashtable类型参数)
②:System.Configuration.DictionarySectionHandler (返回 System.Collections.Hashtable类型数据)
③:System.Configuration.NameValueSectionHandler (返回 System.Configuration.ReadOnlyNameValueCollection类型数据)
1.2.使用
①:System.Configuration.SingleTagSectionHandler
ConfigurationSettings.GetConfig("MySectionGroup/MyFirstSection")["MyFirstSection"];//如果存在分组则参数字符串格式为 “分组名/节点名”
②:System.Configuration.DictionarySectionHandler
ConfigurationManager.GetSection("MySection")["Top"];//如果存在分组则参数字符串格式为 “分组名/节点名”
③:System.Configuration.NameValueSectionHandler
((NameValueCollection)ConfigurationManager.GetSection(“MySectionGroup/MySecondSection”)).AllKeys[0];//如果存在分组则参数字符串格式为 “分组名/节点名”
上述系统默认的配置可以用<appSettings>实现
二:自定义
自定义配置我知道有两种:继承ConfigurationSection和实现IConfigurationSectionHandler接口。
2.1.继承ConfigurationSection
public class CustomSection : System.Configuration.ConfigurationSection
{
[ConfigurationProperty("sectionId", IsRequired = true, IsKey = true)]
public int SectionId
{
get { return (int)base["sectionId"]; }
set { base["sectionId"] = value; }
}
[ConfigurationProperty("sectionValue", IsRequired = false)]
public string SectionValue
{
get { return base["sectionValue"].ToString(); }
set { base["sectionValue"] = value; }
}
}
操作此Section,我们将其动态加入app.config中,并读出来:
public class CustomSectionBroker
{
private CustomSection customSection = null;
public void InsertCustomSection()
{
customSection = new CustomSection();
customSection.SectionId = 1;
customSection.SectionValue = "The First Value";
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.Sections.Add("CustomSection", customSection);
config.Save(ConfigurationSaveMode.Minimal);
}
public int GetCustomSectionID()
{
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
CustomSection cs = config.GetSection("CustomSection") as CustomSection;
return cs.SectionId;
}
}
public void TestCustomSection()
{
CustomSectionBroker cb = new CustomSectionBroker();
cb.InsertCustomSection();
Assert.AreEqual(1, cb.GetCustomSectionID());
}
可以看下现在app.config文件的变化:
<configuration>
<configSections>
<section name="CustomSection" type="Tonnie.Configuration.Library.CustomSection, Tonnie.Configuration.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<sectionGroup name="MySectionGroup">
<section name="MyFirstSection" type="System.Configuration.DictionarySectionHandler"/>
<section name="MySecondSection" type="System.Configuration.DictionarySectionHandler"/>
</sectionGroup>
</configSections>
<CustomSection sectionId="1" sectionValue="The First Value" />
<MySectionGroup>
<MyFirstSection>
<add key="First" value="First Section"/>
</MyFirstSection>
<MySecondSection>
<add key="Second" value="Second Section"/>
</MySecondSection>
</MySectionGroup>
</configuration>
增加了一个单独的Section,名为"CustomSection",并且包含了我们创建的2个 configurationProperty。我们还可以继续作扩展,现在我们的config中section的部分呈现的是<CustomSection sectionId="1" sectionValue="The First Value" /> ,
这样 对于复杂的配置信息仍然不方便,我们是不是可以继续扩展,将其变成比较合理的:
<CustomSection>
<ChildCustomSectionA childId="1" childValue="ChildA"></ChildCustomSectionA>
<ChildCustomSectionB childid="2" childValue=”ChildB”></ChildCustomSectionB>
</CustomSection>
这种方式呢? 我们为<ChildCustomSectionA></ChildCustomSectionA>创建扩展自ConfigurationElement类的子类CustomSectionElementA,然后修改CustomSection类中的Property,使得类型不再是int 或 string,
而是我们创建的新类 CustomSectionElementA。
由于ChildCustomSectionA 和ChildCustomSectionB 的结构相对一致,根据面向对象的开发封闭原则,我们可以先抽象出一个base类,然后让ChildCustomSectionA,ChildCustomSectionB分别继承自此base类,
当以后要添加更多的ChildCustomSectionC,ChildCustomSectionD…时,使用这种Template的设计模式,将更加灵活。
public abstract class CustomSectionElementBase : System.Configuration.ConfigurationElement
{
[ConfigurationProperty("childId", IsRequired = true, IsKey = true)]
public int ChildID
{
get { return (int)base["childId"]; }
set { base["childId"] = value; }
}
[ConfigurationProperty("childValue", IsRequired = true)]
public string ChildValue
{
get { return base["childValue"].ToString(); }
set { base["childValue"] = value; }
}
}
public class CustomSectionElementA : CustomSectionElementBase
{
public CustomSectionElementA()
{
base.ChildID = 1;
base.ChildValue = "ChildA";
}
}
public class CustomSectionElementB : CustomSectionElementBase
{
public CustomSectionElementB()
{
base.ChildID = 2;
base.ChildValue = "ChildB";
}
}
完成了ConfigurationElement的实现,我们可以改写我们上一个例子中定义的CustomSection类了:
public class CustomSectionWithChildElement : System.Configuration.ConfigurationSection
{
private const string elementChildA = "childSectionA";
private const string elementChildB = "childSectionB";
[ConfigurationProperty(elementChildA, IsRequired = true, IsKey = true)]
public CustomSectionElementA ChildSectionA
{
get { return base[elementChildA] as CustomSectionElementA; }
set { base[elementChildA] = value; }
}
[ConfigurationProperty(elementChildB, IsRequired = true)]
public CustomSectionElementB ChildSectionB
{
get { return base[elementChildB] as CustomSectionElementB; }
set { base[elementChildB] = value; }
}
}
public class CustomSectionWithChildElementBroker
{
private CustomSectionWithChildElement customSection = null;
public void InsertCustomSection()
{
customSection = new CustomSectionWithChildElement();
customSection.ChildSectionA = new CustomSectionElementA();
customSection.ChildSectionB = new CustomSectionElementB();
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.Sections.Add("CustomSectionWithChildElement", customSection);
config.Save(ConfigurationSaveMode.Minimal);
}
public int GetCustomSectionChildAID()
{
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
CustomSectionWithChildElement cswe = config.GetSection("CustomSectionWithChildElement") as CustomSectionWithChildElement;
return cswe.ChildSectionA.ChildID;
}
}
将Property改成我们自定义类的形式.测试代码如下:
public void TestCustomSectionWithChildElement()
{
CustomSectionWithChildElementBroker cweb = new CustomSectionWithChildElementBroker();
cweb.InsertCustomSection();
Assert.AreEqual(1, cweb.GetCustomSectionChildAID());
}
看看运行后我们的app.config变成什么样子了:
<configuration>
<configSections>
<section name="CustomSectionWithChildElement" type="Tonnie.Configuration.Library.CustomSectionWithChildElement, Tonnie.Configuration.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<section name="CustomSection" type="Tonnie.Configuration.Library.CustomSection, Tonnie.Configuration.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<sectionGroup name="MySectionGroup">
<section name="MyFirstSection" type="System.Configuration.DictionarySectionHandler"/>
<section name="MySecondSection" type="System.Configuration.DictionarySectionHandler"/>
</sectionGroup>
</configSections>
<CustomSectionWithChildElement>
<childSectionA childId="1" childValue="ChildA" />
<childSectionB childId="2" childValue="ChildB" />
</CustomSectionWithChildElement>
<CustomSection sectionId="1" sectionValue="The First Value" />
<MySectionGroup>
<MyFirstSection>
<add key="First" value="First Section"/>
</MyFirstSection>
<MySecondSection>
<add key="Second" value="Second Section"/>
</MySecondSection>
</MySectionGroup>
</configuration>
下面为我们的CustomSectionWithChildElement外面再加一层SectionGroup:
public class CustomSectionGroup : System.Configuration.ConfigurationSectionGroup
{
[ConfigurationProperty("customSectionA", IsRequired = true, IsKey = true)]
public CustomSectionWithChildElement SectionA
{
get { return base.Sections["customSectionA"] as CustomSectionWithChildElement; }
set
{
this.Sections.Add("customSectionA", value);
}
}
}
public class CustomSectionGroupWithChildElementBroker
{
private CustomSectionWithChildElement customSection = null;
public void InsertCustomSectionGroup()
{
customSection = new CustomSectionWithChildElement();
customSection.ChildSectionA = new CustomSectionElementA();
customSection.ChildSectionB = new CustomSectionElementB();
CustomSectionGroup sectionGroup = new CustomSectionGroup();
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (config.GetSectionGroup("customSectionGroup") == null)
config.SectionGroups.Add("customSectionGroup", sectionGroup);
sectionGroup.SectionA = customSection;
config.Save(ConfigurationSaveMode.Minimal);
}
public int GetCustomSectionChildAID()
{
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
CustomSectionWithChildElement cswe = config.GetSection("customSectionGroup/customSectionA") as CustomSectionWithChildElement;
return cswe.ChildSectionA.ChildID;
}
}
测试一下:
public void TestCustomSectionGroupWithChildElement()
{
CustomSectionGroupWithChildElementBroker cweb = new CustomSectionGroupWithChildElementBroker();
cweb.InsertCustomSectionGroup();
Assert.AreEqual(1, cweb.GetCustomSectionChildAID());
}
没问题,看下现在的app.config,是不是更加结构化了:
<configuration>
<configSections>
<sectionGroup name="MySectionGroup">
<section name="MyFirstSection" type="System.Configuration.DictionarySectionHandler"/>
<section name="MySecondSection" type="System.Configuration.DictionarySectionHandler"/>
</sectionGroup>
<sectionGroup name="customSectionGroup" type="Tonnie.Configuration.Library.CustomSectionGroup, Tonnie.Configuration.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" >
<section name="customSectionA" type="Tonnie.Configuration.Library.CustomSectionWithChildElement, Tonnie.Configuration.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</sectionGroup>
</configSections>
<MySectionGroup>
<MyFirstSection>
<add key="First" value="First Section"/>
</MyFirstSection>
<MySecondSection>
<add key="Second" value="Second Section"/>
</MySecondSection>
</MySectionGroup>
<customSectionGroup>
<customSectionA>
<childSectionA childId="1" childValue="ChildA" />
<childSectionB childId="2" childValue="ChildB" />
</customSectionA>
</customSectionGroup>
</configuration>
以上测试代码是用代码方式修改app.config配置文件,也可以手动添加,2.1内容摘自 http://www.ibeifeng.com/tech.php?id=55401
2.2.实现IConfigurationSectionHandler接口
namespace MyConfigurationTest
{
public class RobsunParaSectionHandler : IConfigurationSectionHandler
{
#region IConfigurationSectionHandler 成員
public object Create(object parent, object configContext, XmlNode section)
{
RobsunPara para = new RobsunPara();
foreach (XmlNode xn in section.ChildNodes)
{
switch (xn.Name)
{
case "path":
para.Path = xn.SelectSingleNode("@value").InnerText;
break;
case "companyName":
para.CompanyName = xn.SelectSingleNode("@value").InnerText;
break;
case "isPrivate":
para.IsPrivate = bool.Parse(xn.SelectSingleNode("@attribute").InnerText);
break;
}
}
return para;
}
#endregion
}
}
以上RobsunParaSectionHandler类实现 IConfigurationSectionHandler 接口.
RobsunPara类(实际就是参数类)的代码如下:
public class RobsunPara
{
#region code
private string _path = "";
private string _companyName = "";
private bool _isPrivate = false;
public string Path
{
get { return _path; }
set { _path = value; }
}
public string CompanyName
{
get { return _companyName; }
set { _companyName = value; }
}
public bool IsPrivate
{
get { return _isPrivate; }
set { _isPrivate = value; }
}
#endregion
}
ConfigurationHander类的创建工作已完成,次handler的工作必须配合如下配置文件的格式(其实的配置文件依赖handler).
这里是web.config(三种配置文件任一,web.config,App.config,machine.config ,前两种会覆盖machine.config,当然这里是没法子在App.config配置了 )
<configuration>
<configSections>
<sectionGroup name="robsunGroup">
<section name="robsunSection" type="RobsunConfigSectionHandler.RobsunParaSectionHandler,RobsunConfigSectionHandler"/>
</sectionGroup>
</configSections>
<robsunGroup>
<robsunSection>
<path value="NONE"/>
<companyName value="Robsun"/>
<isPrivate attribute="true"/>
</robsunSection>
</robsunGroup>
</configuration>
以上2.2内容摘自
http://www.cnblogs.com/panshuiqing/articles/1193860.html