Данная статья может показаться банальной, но иногда что-то полезное забывается, а читать на импортном языке лень и книжки под рукой нет. Поэтому я, обратившись к гуглу, нашел хорошее описание процесса создания обработчика конфигурационной секции файла 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
