Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
188 views
in Technique[技术] by (71.8m points)

Read custom configuration file in C# (Framework 4.0)

I am developing an application in C# under Framework 4.0.

In my application I would like to create separate configuration file that is not the app.config file. The configuration file contains custom configuration sections we developed for the product.

I don't want to reference this file from the app.config using the configSource.

I want to load it at runtime and read it's content.

An example to what I mean is the log4net that allow you to write the configuration in the log4net.config file.

Can anyone help how to do that without writing code that mimcs the code that exists in the framework ?

UPDATE:

based on the answer from Kaido I wrote utility class that reads custom configuration file and has the ability to refresh the Config content when the file on the file system changes.

The usage in this class is as follows:

  1. Get the configuration file content

    // Create configuration reader that reads the files once
    var configFileReader = new CustomConfigurationFileReader("c:\myconfig.config");
    var config = configFileReader.Config;
    
    // Do any action you want with the config object like:
    config.GetSection("my.custom.section");
    
    // or,
    var someVal = config.AppSettings.Settings["someKey"];
    
  2. Get notifications when the configuration file changes

    // Create configuration reader that notifies when the configuraiton file changes
    var configFileReader = new CustomConfigurationFileReader("c:\myconfig.config", true);
    
    // Register to the FileChanged event
    configFileReader.FileChanged += MyEventHandler;
    
    ...
    
    private void MyEventHanler(object sender, EventArgs e)
    {
         // You can safely access the Config property here, it is already contains the new content
    }
    

In the code I used PostSharp in order to validate the constructor input parameter to verify that the log file is not null and that the file exists. You can change the code to make those validation inline in the code (although I recomend to use PostSharp to seperate the application to aspects).

Here is the code:

    using System;
    using System.Configuration;
    using System.IO;
    using CSG.Core.Validation;

    namespace CSG.Core.Configuration
    {
        /// <summary>
        /// Reads customer configuration file
        /// </summary>
        public class CustomConfigurationFileReader
        {
            // By default, don't notify on file change
            private const bool DEFAULT_NOTIFY_BEHAVIOUR = false;

            #region Fields

            // The configuration file name
            private readonly string _configFileName;

            /// <summary>
            /// Raises when the configuraiton file is modified
            /// </summary>
            public event System.EventHandler FileChanged;

            #endregion Fields

            #region Constructor

            /// <summary>
            /// Initialize a new instance of the CustomConfigurationFileReader class that notifies 
            /// when the configuration file changes.
            /// </summary>
            /// <param name="configFileName">The full path to the custom configuration file</param>
            public CustomConfigurationFileReader(string configFileName)
                : this(configFileName, DEFAULT_NOTIFY_BEHAVIOUR)
            {            
            }        

            /// <summary>
            /// Initialize a new instance of the CustomConfigurationFileReader class
            /// </summary>
            /// <param name="configFileName">The full path to the custom configuration file</param>
            /// <param name="notifyOnFileChange">Indicate if to raise the FileChange event when the configuraiton file changes</param>
            [ValidateParameters]
            public CustomConfigurationFileReader([NotNull, FileExists]string configFileName, bool notifyOnFileChange)
            {
                // Set the configuration file name
                _configFileName = configFileName;

                // Read the configuration File
                ReadConfiguration();

                // Start watch the configuration file (if notifyOnFileChanged is true)
                if(notifyOnFileChange)
                    WatchConfigFile();
            }

            #endregion Constructor        

            /// <summary>
            /// Get the configuration that represents the content of the configuration file
            /// </summary>
            public System.Configuration.Configuration Config
            {
                get;
                set;
            }

            #region Helper Methods

            /// <summary>
            /// Watch the configuraiton file for changes
            /// </summary>
            private void WatchConfigFile()
            {
                var watcher = new FileSystemWatcher(_configFileName);
                watcher.Changed += ConfigFileChangedEvent;
            }

            /// <summary>
            /// Read the configuration file
            /// </summary>
            public void ReadConfiguration()
            {
                // Create config file map to point to the configuration file
                var configFileMap = new ExeConfigurationFileMap
                {
                    ExeConfigFilename = _configFileName
                };

                // Create configuration object that contains the content of the custom configuration file
                Config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
            }        

            /// <summary>
            /// Called when the configuration file changed.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void ConfigFileChangedEvent(object sender, FileSystemEventArgs e)
            {
                // Check if the file changed event has listeners
                if (FileChanged != null)
                    // Raise the event
                    FileChanged(this, new EventArgs());
            }

            #endregion Helper Methods
        }
    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
 // Map the roaming configuration file. This
      // enables the application to access 
      // the configuration file using the
      // System.Configuration.Configuration class
      ExeConfigurationFileMap configFileMap =
        new ExeConfigurationFileMap();
      configFileMap.ExeConfigFilename = 
        roamingConfig.FilePath;

      // Get the mapped configuration file.
      Configuration config =
        ConfigurationManager.OpenMappedExeConfiguration(
          configFileMap, ConfigurationUserLevel.None);

from http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.aspx


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...