2014-01-16 6 views
11

Ich habe eine C# .Net-Konsole App, die FTP-Operationen ausführt. Derzeit spezifiziere ich die Einstellungen in einem benutzerdefinierten Konfigurationsabschnitt, z.externe Konfigurationsdatei lesen

<?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> 

Ich möchte in der Befehlszeile eine externe Konfigurationsdatei angeben.

JEDOCH !!! ...

Ich habe erkannt, dass die oben „FtpConfiguration“ Abschnitt nicht wirklich in der app.config der Anwendung gehören nicht. Mein Ziel ist, dass ich viele geplante Aufgaben haben, die meine Konsole App wie folgt ausführen:

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

Folglich Ich glaube, ich habe den falschen Weg gegangen und was ich wirklich will, ist etwas in meiner Gewohnheit zu lesen XML-Dokument, aber weiterhin System.Configuration verwenden, um die Werte zu erhalten ... im Gegensatz zu einem XmlDocument lesen und serialisieren, um Knoten/Elemente/Attribute zu erhalten. (Obwohl ich nicht gegen letzteres bin, wenn mir jemand einen einfachen Code zeigen kann)

Zeiger würden sehr geschätzt werden. Vielen Dank.

Update: Die Antwort, die ich ein Link zu einer anderen Frage Stackoverflow wiederholt akzeptiert war, hier mit meinem Code - unter dem genau war, was ich gesucht habe - mit der OpenMappedExeConfiguration meiner externen Konfigurationsdatei

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"); 
öffnen
+1

nur als Anmerkung, , pa rt von Linq zu Xml. – Magus

Antwort

11

Wenn Sie System.Configuration verwenden möchten, um Ihre benutzerdefinierten Dateien zu öffnen, können Sie diesen Beitrag überprüfen: Loading custom configuration files. Oliver nagelt es sehr geradlinig.

Da Sie Parameter lesen möchten, die an Ihre Anwendung über die Befehlszeile übergeben werden, können Sie diesem MSDN-Beitrag einen Besuch abstatten: Command Line Parameters Tutorial.

Wenn Sie lieber einen benutzerdefinierten Ansatz verwenden möchten, gibt es mehrere Möglichkeiten, dies zu erreichen. Eine Möglichkeit besteht darin, eine Loader-Klasse zu implementieren und Ihre benutzerdefinierten Konfigurationsdateien zu verwenden.

Zum Beispiel wollen wir eine einfache Konfigurationsdatei übernehmen, der wie folgt aussieht:

spec1.config

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

Eine sehr einfache, hashtable-like (Schlüssel-Wert-Paar) Struktur.

Eine implementierte Parser/Leser würde dann wie folgt aussehen:

 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); 
     } 

Inzwischen werden Sie noch in der Lage sein ConfigurationManager.AppSettings[] zu verwenden, aus der ursprünglichen app.config Datei zu lesen.

5

Meine bevorzugte Lösung verwendet ein XDocument. Ich habe es nicht getestet, daher kann es einige kleine Probleme geben, aber das soll meinen Standpunkt verdeutlichen.

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; 

} 

Wird ein Wörterbuch geben die Elementnamen und Werte aus XML der Form enthält:

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

Ich finde diese Lösung schön wegen seiner Gesamt Kürze.

Erneut erwarte ich nicht, dass dies genau so funktioniert wie es ist. Mit XAttributes und XElements und so können Sie definitiv mehr wie Ihr Original machen. Es wird einfach zu filtern sein.

+0

+1, gefällt mir, wie kompakt es auch ist. – OnoSendai

+0

@OnoSendai: Das ist wirklich einer meiner Lieblingsteile von Linq, und ich glaube nicht, dass viele Leute merken, dass es sogar da ist. Es ist jedoch relativ neu, nehme ich an. Die Funktionsweise von Namespaces kann jedoch etwas verwirrend sein. – Magus

12

Wenn Sie den benutzerdefinierten Pfad gehen, würde ich ehrlich gesagt nur JSON verwenden, um die Konfiguration zu speichern und dann deserialize, um es zu laden und zu serialisieren, um es zu schreiben. Json.NET können Sie dies sehr einfach tun.

Ihre XML von:

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

möchte diese in JSON aussehen:

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

Ihre Klassen würde wie folgt aussehen:

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

Sie in ein Objekt Einstellung speichern möchten dies:

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" 
      } 
     } 
    } 
}; 

Sie könnten dann schreiben wie diese in die Datei (oder eine Stream wenn sich eine größere Datei verwenden):

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

Sie könnten dann lesen in der Datei wie folgt (wieder könnten Sie XmlDocument ist die alte Art und Weise xml in C# Handhabung, und während Sie auf jeden Fall kann es tun, würde ich vorschlagen XDocument mit: a Stream statt): wenn Sie sich entscheiden, nur xml parsen

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