In .Net applications, we often see that the project projects generated by VS for us will contain files such as App.config or Web.config. This file is what we call the application configuration file. This file describes some information related to our application, such as database connection, authentication mode, etc. In the program, we can use the ConnectionStrings property of ConfigurationManager to conveniently obtain the database connection string information in the configuration file.
But sometimes, we need to extend it and add some custom elements instead of just using the default configuration. For example, we may need to dynamically load a class and initialize it when the program starts, but this class or initialization data is unknown to us during program design. I believe everyone has encountered such a problem, so I won’t explain it too much here. The best way is to write these things that may change into the configuration file. When you are sure, you only need to modify the configuration file, instead of taking 30 seconds to open VS when the product is about to go online. Go and change the code.
Adding some custom elements to a configuration file is easy and only takes two steps:
1. Register the node name you want to define and the configuration section handler used to process the node in the <configSections> node. The code is as follows:
1 <configSections>2 <section name="dbFactory" type="DbFactory.Configuration.DbFactorySection,DbFactory.Configuration"/>3 </configSections>
2. Add customized nodes at appropriate locations. The code is as follows:
1 <configSections> 2 <section name="dbFactory" type="DbFactory.Configuration.DbFactorySection,DbFactory.Configuration"/> 3 </configSections> 4 <dbFactory> 5 <default factory="sql"></default> 6 <factorys> 7 <add name="sql" assembly="Hello.Data" class="SqlDbFactory" /> 8 <add name="oracle" assembly="Hello.Data" class="OracleDbFactory" /> 9 </ factories>10 </dbFactory>
The custom node has been added, but how do we obtain this configuration information in the program? I believe many of you are experts in playing with XML. If you use some classes under System. This is indeed the case. The master is indeed a master. I really admire him. But if it is implemented in this way, there is really no need for me to write this blog post.
The .Net framework implements many configuration APIs for us to simplify our operations on configuration files. In the first step, we mentioned the configuration section handler, which is used to read and write our customized node information. So how do we implement a configuration section handler? First, let's take a look at the related classes and concepts.
ConfigurationSection: Custom nodes must inherit this class to provide customized processing and programmatic access to the custom configuration section.
ConfigurationElement: It represents an element within the configuration file.
ConfigurationElementCollection: It represents a configuration element that contains a collection of child elements.
With these classes, we can summarize that there are two types of configuration elements in the configuration file.
First, a single configuration element is an element that inherits from ConfigurationElement and does not contain any child elements.
Second, the collection configuration element is an element inherited from ConfigurationElementCollection, which contains a collection of child elements.
Concepts are often relatively abstract. To understand these things, we should explain them in detail based on the examples we gave above.
There are two elements in the <dbFactory> configuration section, namely <default> and <factorys>, and the <factorys> element contains two sub-elements. So here <default> is a single configuration element, and <factorys> is a collection configuration element. We need to implement the classes and their properties corresponding to these elements respectively.
<default> element: It is a single type element, so we inherit ConfigurationElement. There is a factory attribute in this element, so we define it accordingly in the class. The code is as follows:
code
public class DefaultElement: ConfigurationElement { [ConfigurationProperty("factory")] public string Factory { get { return this["factory"] as string; } set { this["factory"] = value; } } }
Note: We need to register the ConfigurationProperty attribute of the property above the property definition.
<factorys> child elements:
code
public class FactoryElement : ConfigurationElement { [ConfigurationProperty( "name" )] public string Name { get { return this["name"] as string; } set { this["name"] = value; } } [ConfigurationProperty("assembly" )] public string Assembly { get { return this["assembly"] as string; } set { this["assembly"] = value; } } [ConfigurationProperty("class")] public string Class { get { return this[" class"] as string; } set { this["class"] = value; } } }
The <factorys> element is a collection element and inherits ConfigurationElementCollection.
code
public class FactoryElements : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new FactoryElement(); } protected override object GetElementKey( ConfigurationElement element ) { return ((FactoryElement)element).Name; } public FactoryElement this[string name] { get { return BaseGet( name ) as FactoryElement; } } }
The ConfigurationElementCollection class is an abstract class, and you should explicitly implement its CreateNewElement method and GetElementKey method.
<dbFactory> node, inherited from ConfigurationSection
code
public class DbFactorySection : ConfigurationSection { [ConfigurationProperty("default")] public DefaultElement DefaultFactory { get { return this["default"] as DefaultElement; } set { this["default"] = value; } } [ConfigurationProperty( "factorys" )] public FactoryElements Factorys { get { return this["factorys"] as FactoryElements; } set { this["factorys"] = value; } } }
The configuration section handler is finally finished. Put these four classes in the same project directory and compile them into a DLL. Where you need to obtain configuration information, reference this DLL and use DbFactorySection section = ConfigurationManager.GetSection( "dbFactory" ) as DbFactorySection; Try it. Is section what you want?