项目配置文件app.config/configuration/configSections

来源:互联网 发布:淘宝店名可以重复吗 编辑:程序博客网 时间:2024/06/06 05:01
<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

0 0
原创粉丝点击