Установка
Данная библиотека доступна для скачивания через NuGet. Или вы можете скачать исходники из GitHub.
Использование
Для демонстрации возможностей библиотеки давайте представим, что нашей программе требуются настройки для подключения к нескольким внешним сервисам, базам данных и наша система должна уметь отправлять письма администраторам системы. Мы решили, что данные настройки будут находится в трех секциях.
<ExternalSystemSettings> <AuthenticationSettings> <Login>DotNetCraft</Login> <Token>qwerty</Token> <Urls> <Url>https://github.com/DotNetCraft/ConfigurationParser</Url> <Url>https://github.com/DotNetCraft/ConfigurationParser</Url> </Urls> </AuthenticationSettings> <StaffSettings Token="{D0C148F7-83C0-41B0-8F18-B47CAB09AD99}" Url="https://github.com/DotNetCraft/ConfigurationParser"/> </ExternalSystemSettings> <DatabasesSettings> <MongoSettings ConnectionString="mongo.url" DatabaseName="DotNetCraft"/> <SqlSettings> <item key="TenantA"> <value> <SqlSettings ConnectionString="sql.TenantA.com"/> </value> </item> <item> <key>TenantB</key> <value> <SqlSettings> <ConnectionString>sql.TenantB.com</ConnectionString> </SqlSettings> </value> </item> </SqlSettings> </DatabasesSettings> <SmtpSettings Host="gmail.com" Sender="no-reply"> <Recipients>clien1@gmail.com;clien2@gmail.com;clien3@gmail.com</Recipients> </SmtpSettings>
Следующим шагом необходимо создать классы, в которых мы будем хранить настройки системы.
#region ExternalSystemSettings class ExternalSystemSettings { public AuthenticationServiceSettings AuthenticationSettings { get; set; } public StaffServiceSettings StaffSettings { get; set; } } class AuthenticationServiceSettings { public string Login { get; set; } public string Token { get; set; } public List<string> Urls { get; set; } } class StaffServiceSettings { public Guid Token { get; set; } public string Url { get; set; } } #endregion #region DatabasesSettings class DatabasesSettings { public MongoDatabaseSettings MongoSettings { get; set; } public Dictionary<string, SqlSettings> SqlSettings { get; set; } } class MongoDatabaseSettings { public string ConnectionString { get; set; } public string DatabaseName { get; set; } } class SqlSettings { public string ConnectionString { get; set; } } #endregion #region Smtp class SmtpSettings { public string Host { get; set; } public string Sender { get; set; } [CustomStrategy(typeof(SplitRecipientsCustomStrategy))] public List<string> Recipients { get; set; } } #endregion
В конфигурационном файле нам необходимо объявить, что мы будем использовать ConfigurationParser.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="ExternalSystemSettings" type="DotNetCraft.ConfigurationParser.SimpleConfigurationSectionHandler, DotNetCraft.ConfigurationParser" /> <section name="DatabasesSettings" type="DotNetCraft.ConfigurationParser.SimpleConfigurationSectionHandler, DotNetCraft.ConfigurationParser" /> <section name="SmtpSettings" type="DotNetCraft.ConfigurationParser.SimpleConfigurationSectionHandler, DotNetCraft.ConfigurationParser" /> </configSections> … </configuration>
Теперь мы можем считать нашу конфигурацию легко и непринужденно:
ExternalSystemSettings externalSystemSettings = (dynamic)ConfigurationManager.GetSection("ExternalSystemSettings"); DatabasesSettings databasesSettings = (dynamic)ConfigurationManager.GetSection("DatabasesSettings");
После выполнения кода у нас будет создано 2 объекта, которые и будут содержать наши настройки. Как вы можете справедливо заметить, мы не считываем SmtpSettings. Это сделано для того, чтобы продемонстрировать дополнительные возможности утилиты.
В различных проектах вам может понадобиться записывать разнообразные настройки в конфигурационные файлы и иметь свою логику как с ними работать. Утилита спроектирована таким образом, что вы можете ее легко расширить путем добавления новой стратегии и покрыть все сценарии, которые вам нужны. Для примера, давайте рассмотрим секцию Recipients:
<Recipients>clien1@gmail.com;clien2@gmail.com;clien3@gmail.com</Recipients>
Эта секция содержит список email-ов, разделенных точкой с запятой. Согласно нашему ТЗ и классу мы должны записать каждый адрес как отдельный элемент в массиве. Для выполнения поставленной задачи нам надо создать класс SplitRecipientsCustomStrategy и реализовать интерфейс ICustomMappingStrategy
class SplitRecipientsCustomStrategy : ICustomMappingStrategy { #region Implementation of ICustomMappingStrategy public object Map(string input, Type itemType) { string[] items = input.Split(';'); List<string> result = new List<string>(); result.AddRange(items); return result; } public object Map(XmlNode xmlNode, Type itemType) { string input = xmlNode.InnerText; return Map(input, itemType); } #endregion }
Внутри нам необходимо реализовать алгоритм распарсивания значения из секции в соответствии с нашим заданием. Необходимо учитывать, что метод Map(string input, Type itemType) вызывается если значение прочитано из атрибута, а метод Map(XmlNode xmlNode, Type itemType) вызывается если значение прочитано из секции. Согласно конфигурационному файлу, значение будет прочитано из секции.
После этого нам необходимо пометить свойство Recipients атрибутом CustomStrategy в котором нужно указать, что за «стратегия» будет использоваться для данного поля:
[CustomStrategy(typeof(SplitRecipientsCustomStrategy))] public List<string> Recipients { get; set; }
Вот и все, теперь мы можем считать настройки электронной почты.
SmtpSettings smtpSettings = (dynamic)ConfigurationManager.GetSection("SmtpSettings");
Как вы видите, ConfigurationParser делает работу по чтению настроек из конфигурационного файла очень удобной и сохраняет кучу времени. При этом она легко расширяется благодаря подключению новых стратегий.
Хотелось бы упомянуть еще об одной возможности данной библиотеки. Это аттрибут PropertyMappingAttribute. Его нужно использовать в случае когда название элемента в конфигурационном файле не совпадает с названием свойства.
Например, у нас есть секция Email, где записывается текущий почтовый адрес пользователя.
<Email>clien1@gmail.com</Email>
А вот в класс для хранения данного значения у нас предусмотрено свойство UserEmail. Чтобы настройки правильно считались необходимо поменить данное свойство аттрибутом PropertyMappingAttribute.
[PropertyMapping("Email")] public string UserEmail { get; set; }
Таким образом названия элементов в конфигурационном файле необязательно должны совпадать с именами свойств.
Если у вас возникнут какие-либо вопросы или предложения, пожалуйста, пишите их в комментариях, я с радостью на них отвечу.
