чтение внешнего файла конфигурации
У меня есть консольное приложение aС#.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 и его сериализации получить узлы/элементы/атрибуты. (Хотя, я не против последнего, если кто-то может показать мне простой код)
Указатели будут высоко оценены. Благодарю.
Обновление: ответ, который я принял, был ссылкой на другой вопрос StackOverflow, который повторялся здесь с моим кодом - ниже которого я точно искал, используя 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");
Ответы
Ответ 1
Если вы хотите использовать 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
.
Ответ 2
Если вы подойдете к пользовательскому пути, я, честно говоря, просто использую 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 = "stackoverflowiscool",
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);
Ответ 3
В моем предпочтительном решении используется 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 и т.д., Вы можете определенно сделать это более похожим на ваш оригинал. Он будет легко фильтроваться.