37 votes

Lire le fichier de configuration personnalisé en C # (Framework 4.0)

Je développe une application en C# sous Framework 4.0.

Dans mon application, j'aimerais créer de fichier de configuration qui n'est pas l'application.fichier de configuration. Le fichier de configuration contient des sections de configuration personnalisée, nous avons développé pour le produit.

Je ne veux pas faire référence à ce fichier à partir de l'app.config à l'aide de la configSource.

Je veux le charger au moment de l'exécution et de lire son contenu.

Un exemple de ce que je veux dire, c'est log4net qui vous permettent d'écrire la configuration dans le log4net.fichier de configuration.

Quelqu'un peut-il aider à la façon de le faire sans avoir à écrire de code qui mimcs le code qui existe dans le cadre ?

Merci, Coby

Mise à JOUR:

basé sur la réponse de Kaido j'ai écrit classe utilitaire qui lit le fichier de configuration personnalisé et a la possibilité d'actualiser la Config du contenu lorsque le fichier sur les modifications du système de fichiers.

L'utilisation de cette classe est comme suit:

  1. Obtenir le fichier de configuration de contenu

    // 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. Recevoir des notifications lorsque les modifications du fichier de configuration

    // 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
    }
    

Dans le code que j'ai utilisé PostSharp afin de valider le constructeur paramètre d'entrée pour vérifier que le fichier journal n'est pas nulle et que le fichier existe. Vous pouvez modifier le code pour faire ceux de validation en ligne dans le code (bien que je vous conseille d'utiliser PostSharp pour séparer l'application d'aspects).

Voici le 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
        }
    }

21voto

Kaido Points 1305
  // 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);
 

à partir de http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.aspx

7voto

christofr Points 1348

Dans le passé, j’utilisais Nini - http://nini.sourceforge.net/manual.php, qui vous permet de lire / écrire des fichiers de configuration personnalisés (XML / Ini / Registry / .Config) au moment de l’exécution.

J'espère que cela t'aides.

2voto

the_drow Points 6141

Mon conseil avec la configuration est de créer votre propre composant de le lire.
Il peut faciliter le développement si, à un certain point, vous aurez à décider ce que vous allez obtenir la configuration à partir d'une autre source comme une base de données ou via un service web.
Cette sorte d'abstraction permet également de vous moquer de la configuration et augmente la testabilité (quelque chose que l' .NET framework n'est pas bien du tout).
Si vous utilisez le format XML comme le format de configuration, je suggère l'utilisation de Linq to XML.
Il est plus facile à lire et à utiliser pour analyser des fichiers XML.

2voto

nittuj Points 21

Vous pouvez essayer le framework Cinchoo pour vos besoins. Cela simplifie le travail de développement en abordant d'abord le code. Définir une classe comme ci-dessous,

 namespace HelloWorld
{
    #region NameSpaces

    using System;
    using Cinchoo.Core.Configuration;

    #endregion NameSpaces

    [ChoConfigurationSection("sample")]
    public class SampleConfigSection : ChoConfigurableObject
    {
        #region Instance Data Members (Public)

        [ChoPropertyInfo("name", DefaultValue="Mark")]
        public string Name;

        [ChoPropertyInfo("message", DefaultValue="Hello World!")]
        public string Message;

        #endregion
    }

    static void Main(string[] args)
    {
        SampleConfigSection sampleConfigSection = new SampleConfigSection();
        Console.WriteLine(sampleConfigSection.ToString());
    }

}
 

Pour la première fois, lorsque vous exécuterez l’application, la section de configuration sera créée dans le fichier .xml [appexename] comme ci-dessous. Ensuite, toute modification apportée à ce fichier sera automatiquement prise en compte.

 <?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="sample" type="Cinchoo.Core.Configuration.ChoNameValueSectionHandler, Cinchoo.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b7dacd80ff3e33de" />
  </configSections>
  <sample>
    <add key="name" value="Mark" />
    <add key="message" value="Hello World!" />
  </sample>
</configuration>
 

0voto

Damian Points 623

Ou utilisez NameValueCollection plus facilement

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X