web-dev-qa-db-fra.com

lecture du fichier de configuration externe

J'ai une application de console c # .Net qui effectue des opérations FTP. Actuellement, je spécifie les paramètres dans une section de configuration personnalisée, par exemple.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="ftpConfiguration" type="FileTransferHelper.FtpLibrary.FtpConfigurationSection, FileTransferHelper.FtpLibrary" />
  </configSections>

  <ftpConfiguration>
      <Environment name="QA">
        <sourceServer hostname="QA_hostname"
                      username="QA_username"
                      password="QA_password"
                      port="21"
                      remoteDirectory ="QA_remoteDirectory" />
        <targetServer downloadDirectory ="QA_downloadDirectory" />

      </Environment>
  </ftpConfiguration>

</configuration>

Je voudrais spécifier, dans la ligne de commande, un fichier de configuration externe.

POURTANT!!!...

Je viens de réaliser que la section "FtpConfiguration" ci-dessus n'appartient pas vraiment à l'application.config de l'application. Mon objectif ultime est d'avoir de nombreuses tâches planifiées qui exécuteront mon application console comme ceci:

FileTransferHelper.exe -c FtpApplication1.config
FileTransferHelper.exe -c FtpApplication2.config
...
FileTransferHelper.exe -c FtpApplication99.config

Par conséquent, je crois que je me suis trompé de chemin et ce que je veux vraiment, c'est quelque chose à lire dans mon document xml personnalisé, mais continuer à utiliser System.Configuration pour obtenir les valeurs ... au lieu de lire un XmlDocument et de le sérialiser en obtenir des nœuds/éléments/attributs. (Bien que je ne sois pas contre ce dernier si quelqu'un peut me montrer un code simple)

Des pointeurs seraient grandement appréciés. Merci.

Mise à jour: La réponse que j'ai acceptée était un lien vers une autre question StackOverflow, répétée ici avec mon code - ci-dessous qui était exactement ce que je cherchais - en utilisant OpenMappedExeConfiguration pour ouvrir mon fichier de configuration externe

ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap();
configFileMap.ExeConfigFilename = @"D:\Development\FileTransferHelper\Configuration\SampleInterface.config";

Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);

FtpConfigurationSection ftpConfig = (FtpConfigurationSection)config.GetSection("ftpConfiguration");
15
Raymond

Si vous souhaitez utiliser System.Configuration pour ouvrir vos fichiers personnalisés, vous pouvez vérifier cette publication: Chargement des fichiers de configuration personnalisés. Oliver le cloue d'une manière très simple.

Étant donné que vous souhaitez lire les paramètres transmis à votre application via la ligne de commande, vous pouvez visiter ce message MSDN: Tutoriel sur les paramètres de ligne de commande.

Si vous préférez utiliser une approche personnalisée, vous pouvez procéder de plusieurs manières. Une possibilité consiste à implémenter une classe de chargeur et à consommer vos fichiers de configuration personnalisés.

Par exemple, supposons un fichier de configuration simple qui ressemble à ceci:

spec1.config

<?xml version="1.0" encoding="utf-8"?>
<Settings>
    <add key="hostname" value="QA_hostname" />
    <add key="username" value="QA_username" />
</Settings>

Une structure très simple, semblable à une table de hachage (paire clé-valeur).

Un analyseur/lecteur implémenté ressemblerait alors à ceci:

        private Hashtable getSettings(string path)
        {
            Hashtable _ret = new Hashtable();
            if (File.Exists(path))
            {
                StreamReader reader = new StreamReader
                (
                    new FileStream(
                        path,
                        FileMode.Open,
                        FileAccess.Read,
                        FileShare.Read)
                );
                XmlDocument doc = new XmlDocument();
                string xmlIn = reader.ReadToEnd();
                reader.Close();
                doc.LoadXml(xmlIn);
                foreach (XmlNode child in doc.ChildNodes)
                    if (child.Name.Equals("Settings"))
                        foreach (XmlNode node in child.ChildNodes)
                            if (node.Name.Equals("add"))
                                _ret.Add
                                (
                                    node.Attributes["key"].Value,
                                    node.Attributes["value"].Value
                                );
            }
            return (_ret);
        }

En attendant, vous pourrez toujours utiliser ConfigurationManager.AppSettings[] pour lire l'original app.config fichier.

16
OnoSendai

Si vous descendez le chemin personnalisé, honnêtement, j'utiliserais simplement JSON pour stocker la configuration, puis désérialiser pour la charger et sérialiser pour l'écrire. Json.NET vous permet de le faire très facilement.

Votre XML de:

<ftpConfiguration>
  <Environment name="QA">
    <sourceServer hostname="QA_hostname"
                  username="QA_username"
                  password="QA_password"
                  port="21"
                  remoteDirectory ="QA_remoteDirectory" />
    <targetServer downloadDirectory ="QA_downloadDirectory" />

  </Environment>
</ftpConfiguration>

Ressemblerait à ceci dans JSON:

{
  "FtpConfiguration": {
    "Environment": {
      "Name": "QA",
      "SourceServer": {
        "HostName": "QA_hostname",
        "UserName": "QA_username",
        "Password": "QA_password",
        "Port": "21",
        "RemoteDirectory": "QA_remoteDirectory"
      },
      "TargetServer": {
        "DownloadDirectory": "QA_downloadDirectory"
      }
    }
  }
}

Vos cours devraient ressembler à:

class Config
{
    public FtpConfiguration FtpConfiguration { get; set; }
}

class FtpConfiguration
{
    public Environment Environment { get; set; }
}

class Environment
{
    public SourceServer SourceServer { get; set; }
    public TargetServer TargetServer { get; set; }
}

class SourceServer
{
    public string HostName { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public int Port { get; set; }
    public string RemoteDirectory { get; set; }
}

class TargetServer
{
    public string DownloadDirectory { get; set; }
}

Vous enregistrez le paramètre dans un objet comme celui-ci:

var config = new Config()
{
    FtpConfiguration = new FtpConfiguration()
    {
        Environment = new Environment()
        {
            SourceServer = new SourceServer()
            {
                HostName = "localhost",
                UserName = "jaxrtech",
                Password = "stackoverflowiscool",
                Port = 9090,
                RemoteDirectory = "/data",
            },
            TargetServer = new TargetServer()
            {
                DownloadDirectory = "/downloads"
            }
        }
    }
};

Vous pouvez alors écrire dans le fichier comme ceci (ou utiliser un Stream si c'est un fichier plus gros):

string json = JsonConvert.SerializeObject(config);
File.WriteAllText("config.json", json);

Vous pouvez alors lire dans le fichier comme ceci (encore une fois, vous pouvez utiliser un Stream à la place):

string json = File.ReadAllText("config.json");
Config config = JsonConvert.DeserializeObject<Config>(json);
12
Josh Bowden

Ma solution préférée utilise un XDocument. Je ne l'ai pas testé, il peut donc y avoir quelques petits problèmes, mais c'est pour démontrer mon point.

public Dictionary<string, string> GetSettings(string path)
{

  var document = XDocument.Load(path);

  var root = document.Root;
  var results =
    root
      .Elements()
      .ToDictionary(element => element.Name.ToString(), element => element.Value);

  return results;

}

Renvoie un dictionnaire contenant les noms et les valeurs des éléments du xml du formulaire:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <hostname>QA_hostname</hostname>
  <username>QA_username</username>
</root>

Je trouve cette solution agréable en raison de sa brièveté globale.

Encore une fois, je ne m'attends pas à ce que cela fonctionne exactement tel quel. En utilisant XAttributes et XElements et autres, vous pouvez certainement rendre cela plus semblable à votre original. Il sera facile de filtrer.

7
Magus