Transfer from https://www.cnblogs.com/tonnie/archive/2010/12/17/appconfig.html
In general projects, in order to make your code more flexible, more convenient to adjust, reduce unnecessary hard code, we have to add a lot of configuration information in config, generally can choose. NET comes with a configuration file in the form of app. Config or Web. config to complete the configuration work. NET provides several configuration-related classes to support the easy completion of configuration file read-write settings:
System.Configuration.ConfigurationSectionGroupThe assambly that you normally use in your project maintain a 1:1 correspondence, which makes the structure relatively clear and the responsibilities clear. Of course you can not use it, so once your assambly is being reused elsewhere, it becomes difficult to find the appropriate config information.
System.Configuration.ConfigurationSectionMaintain a relatively independent configuration section, which is declared under the <ConfigSections></ConfigSections> node now. We are familiar with <appSettings></appSettings> and <connectionStrings></connectionStrings/> is. NET is a section reserved for us.
System.Configuration.ConfigurationElementCollection & System.Configuration.ConfigurationElement is a collection of specific configuration information and configuration information under the section. Here's a look at how to use these classes to play with App. Config 1. The initial usage of the primary play is of course using <appsettings/> we add in app. Config
<configuration> <appSettings> <add key= "myconfigstring" value= "Test Config Data"/> </appSettings></configuration>
Access it
public class Appsettingconfig {public string resultvalue; Public Appsettingconfig () { this.resultvalue = configurationmanager.appsettings["myconfigstring"]. ToString (); } } [TestMethod] public void Testappsettingconfignode () { Appsettingconfig Appcon = new Appsettingconfig (); Assert.AreEqual ("Test Config Data", appcon.resultvalue); } No problem!
Let's add a section to see How to access:
<configuration> <configSections> <sectiongroup name= "Mysectiongroup" > <section Name= "Myfirstsection" type= "System.Configuration.DictionarySectionHandler"/> <section name= " Mysecondsection "type=" System.Configuration.DictionarySectionHandler "/> </sectionGroup> </ configsections> <MySectionGroup> <MyFirstSection> <add key= "First" value= "first section "/> </MyFirstSection> <MySecondSection> <add key=" Second "value=" Second section "/> </MySecondSection> </MySectionGroup></configuration>
Note that we give System.Configuration.DictionarySectionHandler in the type of section, which limits our use of <add in specific configurationelement. key= "" value= ""/> form, so that our GetSection () method returns a Idictory object, we can get the corresponding value according to key
public class Sectionconfig {public string resultvalue; Public Sectionconfig () { System.Configuration.Configuration config = Configurationmanager.openexeconfiguration (configurationuserlevel.none); IDictionary dic = configurationmanager.getsection ("Mysectiongroup/mysecondsection") as IDictionary; This.resultvalue = dic["Second"]. ToString (); } }
[TestMethod] public void Testsectiongroupconfignode () { Sectionconfig sc = new Sectionconfig (); Assert.AreEqual ("first section", Sc.resultvalue); }
Still no problem.
2. Intermediate Play
. NET supports the extension of the above mentioned configuration class, we can define our own section.
Inheriting from the base class System.configuration.configurationsection,configurationsection has provided an indexer to get the settings data.
Add the ConfigurationProperty attribute in the class to define the element in the section:
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;} } }
To manipulate this section, we add it dynamically to the App. config and read it:
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 = Configurationmana Ger. Openexeconfiguration (Configurationuserlevel.none); CustomSection cs = config. GetSection ("CustomSection") as CustomSection; Return CS. SectionID; }} [TestMethod] public void testcustomsection () {Customsectionbroker cb = new CUSTOMSECTIONB Roker (); Cb. InsertcustomsectIon (); Assert.AreEqual (1, CB. Getcustomsectionid ()); }
You can see the changes to the app. Config file now:
<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>
Added a separate section named "CustomSection" and contained the 2 ConfigurationProperty we created. We can also continue to expand, and now the section in our config is presented with the <customsection sectionid= "1" sectionvalue= "the first Value"/>, This is still inconvenient for the complex configuration information, we can not continue to expand, it becomes a more reasonable <customsection><childcustomsectiona childid=1 childvalue= "Childa" ></childcustomsectiona><childcustomsectionb childid=2 childvalue= "ChildB" ></ Childcustomsectionb></customsection> this way? We create a subclass Customsectionelementa for <ChildCustomSectionA></ChildCustomSectionA> that extends from the ConfigurationElement class, The property in the CustomSection class is then modified so that the type is no longer int or string, but rather the new class Customsectionelementa that we created. Because Childcustomsectiona And CHILDCUSTOMSECTIONB's structure is relatively consistent, according to the object-oriented development of the closure principle, we can first abstract a base class, and then let Childcustomsectiona, Childcustomsectionb inherit from this base class separately, when you want to add more childcustomsectionc,childcustomsectiond ... , you will be more flexible when using this template design pattern.
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"; } }
Having completed the implementation of the configurationelement, we can rewrite the CustomSection class as defined in our previous example:
public class CustomSectionWithChildElement:System.Configuration.ConfigurationSection {Private Const string Elem Entchilda = "Childsectiona"; Private Const string ELEMENTCHILDB = "Childsectionb"; [ConfigurationProperty (Elementchilda, Isrequired=true, iskey=true)] publicCustomsectionelementaChildsectiona {get {return Base[elementchilda] as Customsectionelementa;} set {Base[elementchilda] = value;} } [ConfigurationProperty (elementchildb, isrequired = true)] PublicCUSTOMSECTIONELEMENTB 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 = Configurati Onmanager.openexeconfiguration (Configurationuserlevel.none); CustomseCtionwithchildelement cswe = config. GetSection ("Customsectionwithchildelement") as customsectionwithchildelement; Return Cswe. Childsectiona.childid; } }
The red font is the place to change, changing the property to the form of our custom class. The test code is as follows:
[TestMethod] public void Testcustomsectionwithchildelement () { Customsectionwithchildelementbroker cweb = new Customsectionwithchildelementbroker (); Cweb. Insertcustomsection (); Assert.AreEqual (1, Cweb. Getcustomsectionchildaid ()); }
See what our app. config looks like after the run:
<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 "> <sectio n name= "myfirstsection" type= "System.Configuration.DictionarySectionHandler"/> <section name= " Mysecondsection "type=" System.Configuration.DictionarySectionHandler "/> </sectionGroup> </configsecti Ons><CustomSectionWithChildElement> <childsectiona childid= "1" childvalue= "Childa"/> <childsection B childid= "2" childvalue= "Childb"/> </CustomSectionWithChildElement><customsection sectionid= "1" sectionvalue= "the first Value"/> <MySectionGroup> <MyFirstSection> <add key= "First" value= "first section"/> </MyFirstSection> <MySecondSection> <add key= "S Econd "value=" Second section "/> </MySecondSection> </MySectionGroup></configuration>
Cool, seems to have finished our request.
Below we add a layer of sectiongroup outside of our customsectionwithchildelement.
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 = n Ull 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 = Configurati Onmanager.openexeconfiguration (ConfiguRationuserlevel.none); Customsectionwithchildelement cswe = config. GetSection ("Customsectiongroup/customsectiona") as customsectionwithchildelement; Return Cswe. Childsectiona.childid; } }
Test it:
[TestMethod] public void Testcustomsectiongroupwithchildelement () { Customsectiongroupwithchildelementbroker cweb = new Customsectiongroupwithchildelementbroker (); Cweb. Insertcustomsectiongroup (); Assert.AreEqual (1, Cweb. Getcustomsectionchildaid ()); } No problem, look at the current app. Config, is not more structured:
<configuration> <configSections> <sectiongroup name= "Mysectiongroup" > <section name= "Myfirst section "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=" Customse Ctiona "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"/& Gt </MyFirstSection> <MySecondSection> <add key= "Second" value= "Second section"/> </myseconds Ection> </MySectionGroup><customSectionGroup> <customSectionA> <childsectiona childid= "1" childvalue= "Childa"/> <childsectionb childid= "2" childvalue= "Childb"/> </customSectionA> </customSectionGroup></configuration>
3 Advanced Gameplay
So far, you may have a certain understanding of app. Config, we can continue to expand the. NET framework to provide our class, from Sectiongroup,section,elementcollection,element The first level of assembly from top to bottom is in a form that conforms to the engineering project configuration file. You can abstract a base class when you encounter a similar type attribute for a possible configuration element. For example, you can abstract a base class from the section, or elementcollection,element an abstract class (which can be an abstract generic class) on this level. Add generics at the same time to better support extensions. Specific examples are given again next time.
Enclosed All code:/files/tonnie/tonnie.configuration.rar
A little bit of experience, welcome to communicate ...
Step by step teach you to play the. NET Framework configuration File App. Config