Чтение внешнего файла конфигурации

У меня есть консольное приложение AC# .Net, которое выполняет операции FTP. В настоящее время я задаю настройки в разделе пользовательских настроек, например

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

Я хотел бы указать в командной строке внешний файл конфигурации.

ТЕМ НЕ МЕНИЕ!!!...

Я только что понял, что приведенный выше раздел "FtpConfiguration" не относится к app.config приложения. Моя конечная цель состоит в том, чтобы у меня было много запланированных задач, которые будут выполнять мое консольное приложение, например:

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

Следовательно, я считаю, что я пошел по неверному пути, и мне действительно нужно что-то прочитать в моем пользовательском XML-документе, но я продолжаю использовать System.Configuration для получения значений... в отличие от чтения XmlDocument и его сериализации в получить узлы / элементы / атрибуты. (Хотя я не против последнего, если кто-то может показать мне простой код)

Указатели будут с благодарностью. Благодарю.

Обновление: ответ, который я принял, был ссылкой на другой вопрос Stackru, повторенный здесь с моим кодом - ниже, который был именно тем, что я искал - используя OpenMappedExeConfiguration, чтобы открыть мой внешний файл конфигурации

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

3 ответа

Решение

Если вы хотите использовать System.Configuration для открытия ваших пользовательских файлов, вы можете проверить это сообщение: Загрузка пользовательских файлов конфигурации. Оливер прибивает это очень прямым способом.

Поскольку вы хотите прочитать параметры, передаваемые вашему приложению через командную строку, вы можете посетить это сообщение MSDN: Руководство по параметрам командной строки.

Если вы предпочитаете использовать индивидуальный подход, есть несколько способов сделать это. Одна возможность - реализовать класс загрузчика и использовать ваши пользовательские файлы конфигурации.

Например, давайте предположим простой файл конфигурации, который выглядит следующим образом:

spec1.config

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

Очень простая структура, похожая на хеш-таблицу (пара ключ-значение).

Реализованный парсер / читатель будет выглядеть примерно так:

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

Между тем, вы все равно сможете использовать ConfigurationManager.AppSettings[] читать с оригинала app.config файл.

Если вы идете по нестандартному пути, я, честно говоря, просто использовал бы JSON для хранения конфигурации, а затем десериализовал для загрузки и сериализации для записи. Json.NET позволяет сделать это очень легко.

Ваш XML из:

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

Будет выглядеть так в JSON:

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

Ваши занятия будут выглядеть так:

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

Вы бы сохранили настройки в объект, как это:

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

Затем вы можете написать в файл, как это (или использовать Stream если это больший файл):

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

Затем вы можете прочитать в файле, как это (снова вы могли бы использовать Stream вместо):

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

Мое предпочтительное решение использует XDocument. Я не проверял это, поэтому могут быть небольшие проблемы, но это должно продемонстрировать мою точку зрения.

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;

}

Вернет словарь, содержащий имена элементов и значения из xml формы:

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

Я нахожу это решение хорошим из-за его краткости.

Опять же, я не ожидаю, что это будет работать именно так, как есть. Используя XAttributes и XElements и т. Д., Вы определенно можете сделать это больше похожим на ваш оригинал. Это будет легко отфильтровать.

Другие вопросы по тегам