Three years ago, I shared how to separate the configuration section in web. config. Because some projects are too large, N multiple configuration sections are saved in web. config. The disadvantages are as follows:
1: it is not easy to manage. When you want to find a configuration section and look at the code on the page, you are at a loss. Therefore, you only need ctrl + f to solve this problem.
2: there are also errors during deployment. The deployment personnel should add one by one according to the deployment documents you have written, which is time-consuming and error-prone, for example, if you accidentally overwrite other nodes.
3: modifying the configuration section in web. config will cause the site to restart.
4: the access configuration section is not simple enough and error-prone.
I mentioned earlier that the configuration section is separated from the web. config file to save the configuration section to a separate file. For specific solutions, refer to the previous article (How to split web. config), It has not been used for a long time. Recently, it was found that there is a problem in the reuse of multiple projects, that is, each project needs to write a short piece of code, the following is my optimization process. Let's take a look at the original workload:
First, Webconfig, which is the content in the framework, is the only place where it can be reused. It is an entry, and all configuration files are referenced through it, such as the configuration class for accessing the Hotel, WebConfig. Hotel. Movie name. The Code is as follows:
View Code
Public partial class WebConfig
{
/// <Summary>
/// Start the configuration class
/// </Summary>
Public static void OnStart (string configFilePath, FileUpdate fileUpdate)
{
# Region independent configuration files
// Perform the delegate method to update the configuration class at the first startup.
FileUpdate (configFilePath );
// Start file monitoring
Log4netFileWatchHelper. StartWatching (fileUpdate, configFilePath );
# Endregion
}
/// <Summary>
/// Config/disk path of the Web Folder
/// </Summary>
Public static string ConfigFilePathRoot
{
Get;
Set;
}
}
1: contains an important method OnStart, which can initialize the configuration file. In fact, this initialization can also be omitted, because the Initialization Configuration class can be changed to the delayed loading mode.
2: the attribute of a configuration file path, which identifies the directory where all configuration files of this project class are stored. You can specify this attribute during program initialization.
2. Custom configuration file class. For example, we can add a configuration class for data access.
View Code
[Serializable]
Public class DataAccessConfig
{
# Configuration file attributes to be serialized by region
/// <Summary>
/// Database information list
/// </Summary>
Public List <DataBase> DataBaseList {get; set ;}
# Endregion
# Region does not need to be serialized relative to the sub-file path in the Config folder.
/// <Summary>
/// The sub-file path of the Config folder does not need to be serialized.
/// </Summary>
[NonSerialized ()]
Private static string m_SubFilePath = @ "DataAccessConfig. config ";
/// <Summary>
/// Sub-file path (excluding the part after the config folder path)
/// </Summary>
Public static string SubFilePath
{
Get {return m_SubFilePath ;}
Set {m_SubFilePath = value ;}
}
# Endregion
Public static DataAccessConfig CreateInstance ()
{
FileUpdate fileUpdate = new FileUpdate (WebConfig. DataAccessConfigOnUpdate );
String configFilePath = WebConfig. ConfigFilePathRoot + DataAccessConfig. SubFilePath;
If (! File. Exists (configFilePath ))
{
Return null;
}
DataAccessConfig config = SerializationHelper. Load (typeof (DataAccessConfig), configFilePath) as DataAccessConfig;
// Start file monitoring
Log4netFileWatchHelper. StartWatching (fileUpdate, configFilePath );
Return config;
}
}
Public partial class WebConfig
{
# Region Step 2: Add an entry for the DataAccessConfig class
/// <Summary>
/// Private variable corresponding to the property
/// </Summary>
Private static DataAccessConfig m_DataAccessConfig = null;
/// <Summary>
/// Attribute accessors. This class can be accessed through WebConfig. SimpleFileDemoConfig.
/// </Summary>
Public static DataAccessConfig
{
Get
{
If (m_DataAccessConfig = null)
Interlocked. CompareExchange <DataAccessConfig> (ref m_DataAccessConfig,
DataAccessConfig. CreateInstance (), null );
Return m_DataAccessConfig;
}
}
# Endregion
# Region Step 3: add an update function for the DataAccessConfig class
/// <Summary>
/// Update a function
/// </Summary>
/// <Param name = "status"> </param>
Public static void DataAccessConfigOnUpdate (object status)
{
Lock (WebConfig. DataAccessConfig)
{
Try
{
M_DataAccessConfig = DataAccessConfig. CreateInstance ();
}
Catch (Exception ex)
{
Throw ex;
}
}
}
# Endregion
}
This code is the part we want to implement and cannot be reused. We need to improve the overall perception. Problem Analysis:
1: Because you need to use the static call method, to use the static attribute call of WebConfig, you need to add the attributes of the custom configuration class to the WebConfig class, for example, we add a Hotel-related configuration class, but want to WebConfig. hotel, you need to add a static attribute method. Here, you can modify it a little. In the end, you can write only custom configuration classes when configuring custom configuration classes, instead of WebConfig classes.
2: The CreateInstance in the custom configuration class should also be reused.
The principle is that the custom configuration class does not care about how to read the configuration file, but only about its own configuration attributes.
Improved Version:
1: For WebConfig. Custom class method. Here, the method I modified is not the best, and it is not smooth before modification, but the code is indeed streamlined. The idea is to generate a generic configuration class in the WebConfig class.
Public partial class WebConfig <T>: WebConfig where T: class
Here, the wildcard version of WebConfig is added, and WebConfig is extracted as the base class. The WebConfig class contains an attribute, that is, the path of the configuration file folder.
/// <Summary>
/// Config/disk path of the Web Folder
/// </Summary>
Public static string ConfigFilePathRoot
{
Get;
Set;
}
WebConfig <T> mainly aims to generate the T-type configuration class. Here, the Code originally in the custom configuration class is extracted to WebConfig <T>:
View Code
/// <Summary>
/// Private variable corresponding to the property
/// </Summary>
Private static T m_DataAccessConfig;
/// <Summary>
/// Attribute accessors. This class can be accessed through WebConfig. SimpleFileDemoConfig.
/// </Summary>
Public static T DataAccessConfig
{
Get
{
If (m_DataAccessConfig = null)
Interlocked. CompareExchange <T> (ref m_DataAccessConfig,
CreateInstance (), null );
Return m_DataAccessConfig;
}
}
/// <Summary>
/// Update a function
/// </Summary>
/// <Param name = "status"> </param>
Public static void DataAccessConfigOnUpdate (object status)
{
Lock (WebConfig <T>. DataAccessConfig)
{
Try
{
M_DataAccessConfig = CreateInstance ();
}
Catch (Exception ex)
{
Throw ex;
}
}
}
2: encapsulate the methods used to generate instances for custom configuration classes.
Private static T CreateInstance ()
{
SubFilePath = typeof (T). Name + ". config ";
String configFilePath = WebConfig <T>. ConfigFilePathRoot + SubFilePath;
If (! File. Exists (configFilePath ))
{
Return null;
}
T config = SerializationHelper. Load (typeof (T), configFilePath) as T;
// Start file monitoring
FileWatch (configFilePath );
Return config;
}
With the above extraction encapsulation, the following is the revised custom class. So far, the cost of writing a custom configuration class is very low:
[Serializable]
Public class MyConfig: WebConfig <DataAccessConfig>
{
# Configuration file attributes to be serialized by region
Public string ExpenseTemplateFile {get; set ;}
Public bool Switch {get; set ;}
# Endregion
}
Finally, we add a configuration file with the same name as the custom configuration class.
<? Xml version = "1.0" encoding = "UTF-8"?>
<MyConfig>
<ExpenseTemplateFile> ssssssss3 </ExpenseTemplateFile>
<Switch> false </Switch>
</MyConfig>
Client call method:
WebConfig <MyConfig>. DataAccessConfig. Switch
Although this revision is not perfect, it has played a significant role in multiple projects. It is easy to write and call. The only thing that is not satisfied with the change is to write it like this: webConfig <MyConfig>, no previous WebConfig. myConfig is comfortable.