Данная статья может показаться банальной, но иногда что-то полезное забывается, а читать на импортном языке лень и книжки под рукой нет. Поэтому я, обратившись к гуглу, нашел хорошее описание процесса создания обработчика конфигурационной секции файла app.config в .net приложениях, перевел его, дополнил замечаниями (курсив) и комментариями и решил опубликовать.
Я уверен, что многим из вас приходилось использовать файл конфигурации App.Config для хранения инициализирующих или конфигурационных данных приложения. И я так же уверен в том, что многим из вас хотелось создать в данном файле свои собственные структуры для хранения настроек. Но в итоге приходилось использовать встроенные возможности секции <appSettings> и получать значения, используя конструкцию вида:
Что ж, я давно хотел выяснить, как использовать возможности класса ConfigurationSection для описания и загрузки данных, определенных в моем собственном формате. После нескольких часов экспериментов и гугления я смог создать свою структуру данных в файле конфигурации и воспользоваться ей в своем приложении.
Итак, для того что бы загрузить свою структуру данных из файла App.Config нам потребуются следующие классы:
Первое, что нам потребуется сделать, это добавить в наше приложение файл app.Config (если, конечно, вы этого еще не сделали). После чего открываем данный файл и копипастим следующий код между тегами <configuration>:
Замечание: данная секция должна располагаться в самом начале файла конфигурации, т.е. сразу после тега <configuration>, иначе будут ошибки инициализации конфигурации.
Далее создадим нашу собственную секцию, которая будет реализовывать нашу собственную модель данных:
Замечание: если кому-то не нравиться добавление узлов командой add в данном примере, то всегда можно сделать свой собственный префикс, используя следующий код:
при определении коллекции элементов в структуре данных. Тогда в конфигурационном файле можно будет писать так:
Закончим модификации в файле конфигурации и перейдем к организации взаимодействия нашего приложения с ним.
Первым делом создадим класс-наследник от ConfigurationSection, что позволит нам взаимодействовать с нашей секцией в файле конфигурации через ConfigurationManager во время исполнения программы.
Атрибут ConfigurationProperty( «Folders» ) требуется для сопоставления свойства FolderItems с корневым узлом нашей структуры данных.
Класс FoldersCollection является наследником ConfigurationElementCollection, который обеспечивает взаимодействие с коллекцией наших элементов, описанных в app.config. Определяется класс так:
Последним нам нужно создать ConfigurationElement, класс который свяжет нас с конечными данными, определенными в конфигурационном файле.
Атрибут ConfigurationProperty(«folderType») требуется для того, что бы проассоциировать имя xml-атрибута в файле конфигурации. Остальные параметры атрибута такие как DefaultValue="", IsKey=true, IsRequired=true определяют только различные опции применимые к свойствам.
Замечание: автор умалчивает, что при стандартном способе использования сеттер свойства FolderType, работать не будет, т.к. файл конфигурации обычно доступен только на чтение. Для того что бы представлялось возможным производить запись в файл конфигурации следует делать, например, так:
Итак, мы имеем все необходимые данные и классы, которые предоставляют нам возможность хранить в конфигурационном файле app.config пользовательскую структуру данных.
Использовать данный подход можно так:
При этом не забываем прописать System.Configuration в список подключаемых пространств имен.
Автор: Derik Whittaker
Я уверен, что многим из вас приходилось использовать файл конфигурации App.Config для хранения инициализирующих или конфигурационных данных приложения. И я так же уверен в том, что многим из вас хотелось создать в данном файле свои собственные структуры для хранения настроек. Но в итоге приходилось использовать встроенные возможности секции <appSettings> и получать значения, используя конструкцию вида:
ConfigurationManager.AppSettings["MyKey"]
Что ж, я давно хотел выяснить, как использовать возможности класса ConfigurationSection для описания и загрузки данных, определенных в моем собственном формате. После нескольких часов экспериментов и гугления я смог создать свою структуру данных в файле конфигурации и воспользоваться ей в своем приложении.
Итак, для того что бы загрузить свою структуру данных из файла App.Config нам потребуются следующие классы:
- ConfigurationSection — Этот объект вернет нам пользовательскую секцию.
- ConfigurationElementCollection — Это собственно коллекция элементов, которые мы определим в пользовательской секции.
- ConfigurationElement — Это сам элемент, описывающий какую-от определенную вами сущность.
Первое, что нам потребуется сделать, это добавить в наше приложение файл app.Config (если, конечно, вы этого еще не сделали). После чего открываем данный файл и копипастим следующий код между тегами <configuration>:
<configSections>
<!--
name = Имя, которое используется для ссылки на данный раздел в файле настройки.
type = Обработчик раздела настроек. Включает две секции: полный путь - пространство имен обработчика наших данных + имя самого обработчика, наименование сборки, где данный класс располагается.
-->
<section name="StartupFolders" type="ConfigSectionTester.StartupFoldersConfigSection, ConfigSectionTester"/>
</configSections>
Замечание: данная секция должна располагаться в самом начале файла конфигурации, т.е. сразу после тега <configuration>, иначе будут ошибки инициализации конфигурации.
Далее создадим нашу собственную секцию, которая будет реализовывать нашу собственную модель данных:
<StartupFolders>
<Folders>
<add folderType="A" path="c:\foo" />
<add folderType="B" path="C:\foo1" />
</Folders>
</StartupFolders>
Замечание: если кому-то не нравиться добавление узлов командой add в данном примере, то всегда можно сделать свой собственный префикс, используя следующий код:
[ConfigurationCollection( typeof( FolderElement ) ), AddItemName = "Folder"]
public class FoldersCollection : ConfigurationElementCollection
{
при определении коллекции элементов в структуре данных. Тогда в конфигурационном файле можно будет писать так:
<StartupFolders>
<Folders>
<Folder folderType="A" path="c:\foo" />
<Folder folderType="B" path="C:\foo1" />
</Folders>
</StartupFolders>
Закончим модификации в файле конфигурации и перейдем к организации взаимодействия нашего приложения с ним.
Первым делом создадим класс-наследник от ConfigurationSection, что позволит нам взаимодействовать с нашей секцией в файле конфигурации через ConfigurationManager во время исполнения программы.
public class StartupFoldersConfigSection : ConfigurationSection
{
[ConfigurationProperty( "Folders" )]
public FoldersCollection FolderItems
{
get { return ( (FoldersCollection)( base[ "Folders" ] ) ); }
}
}
Атрибут ConfigurationProperty( «Folders» ) требуется для сопоставления свойства FolderItems с корневым узлом нашей структуры данных.
Класс FoldersCollection является наследником ConfigurationElementCollection, который обеспечивает взаимодействие с коллекцией наших элементов, описанных в app.config. Определяется класс так:
[ConfigurationCollection( typeof( FolderElement ) )]
public class FoldersCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new FolderElement();
}
protected override object GetElementKey( ConfigurationElement element )
{
return ( (FolderElement)( element ) ).FolderType;
}
public FolderElement this[int idx ]
{
get{return (FolderElement) BaseGet(idx); }
}
}
Последним нам нужно создать ConfigurationElement, класс который свяжет нас с конечными данными, определенными в конфигурационном файле.
public class FolderElement : ConfigurationElement
{
[ConfigurationProperty("folderType", DefaultValue="", IsKey=true, IsRequired=true)]
public string FolderType
{
get {return ((string) (base["folderType"]));}
set{base["folderType"] = value; }
}
[ConfigurationProperty( "path", DefaultValue = "", IsKey = false, IsRequired = false )]
public string Path
{
get{return ( (string)( base[ "path" ] ) ); }
set{base[ "path" ] = value; }
}
}
Атрибут ConfigurationProperty(«folderType») требуется для того, что бы проассоциировать имя xml-атрибута в файле конфигурации. Остальные параметры атрибута такие как DefaultValue="", IsKey=true, IsRequired=true определяют только различные опции применимые к свойствам.
Замечание: автор умалчивает, что при стандартном способе использования сеттер свойства FolderType, работать не будет, т.к. файл конфигурации обычно доступен только на чтение. Для того что бы представлялось возможным производить запись в файл конфигурации следует делать, например, так:
Configuration cfg = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
StartupFoldersConfigSection section = (StartupFoldersConfigSection)cfg.Section["StartupFolders"];
if ( section != null )
{
System.Diagnostics.Debug.WriteLine( section.FolderItems[0].FolderType );
System.Diagnostics.Debug.WriteLine( section.FolderItems[0].Path );
section.FolderItems[0].Path = "C:\\Nanook";
cfg.Save(); //устанавливает перенос на новую строку и производит проверку <exename>.vshost.exe.config файла в вашей отладочной папке.
}
Итак, мы имеем все необходимые данные и классы, которые предоставляют нам возможность хранить в конфигурационном файле app.config пользовательскую структуру данных.
Использовать данный подход можно так:
StartupFoldersConfigSection section = (StartupFoldersConfigSection)ConfigurationManager.GetSection( "StartupFolders" );
if ( section != null )
{
System.Diagnostics.Debug.WriteLine( section.FolderItems[ 0 ].FolderType );
System.Diagnostics.Debug.WriteLine( section.FolderItems[ 0 ].Path );
}
При этом не забываем прописать System.Configuration в список подключаемых пространств имен.
Автор: Derik Whittaker