XML Конфигурация IoC контейнера
Библиоетка создавалась для загрузки и применения конфигурации к IoC контейнеру, она не предназначена для конфигурирования контейнера во время выполнения, большинство контейнеров уже обладают данным функционалом.
На данный момент поддерживается единственный вид контейнера - Unity Container
Unity уже обладает средствами загрузки конфигурации из XML, данная библиотека реализует аналогичный функционал, кроме того, позволяет решать следующие задачи:
- Конфигурация является простым Xml документом, который можно получить из любого источика и не ограничивается
.config
файлами приложения - Включение существующе конфигурации
<include href='config.xml'/>
в текущую - Поддержка сериализованных объектов в качестве регистраций сервисов и параметров
- Поддержка специфиакции генериков любой вложенности, например
Dictionary{Foo,Bar{Int32}}
- Поддержка фабрик в XML конфигурации
- Расширение схемы XML конфигурации собственными элементами
Общая архитектура
Пространство имен Implab.ServiceHost.Unity
содержит в себе классы для загрузки и применения XML конфигурации к IoC контейнеру.
Применение конфигурации к контейнеру состоит из следующих основных шагов:
- Настраивается схема
ContainerConfigurationSchema
XML конфигурации контейнера - Загружается документ и десереализуется в виде
ContainerElement
- Создается
ContainerBuilder
при помощи которого применяются настройки изContainerElement
к контейнеру
Схема ContainerConfigurationSchema
определяет элементы документа, которые могут быть использованы в конфигурации контейнера, позволяет создать XmlSerializer
, который используется для загрузки конфигурации.
ContainerBuilder
- основной класс, который используется для применения конфигурации к контейнеру, он добавляет записи регистрации сервисов из конфигурации в контейнер.
ContainerElement
- Конфигурация контейнера, которая загружается из документа, состоит из директив для ContainerBuilder
, а также из записей регистрации сервисов.
В библиотеки приняты следующие правила именования классов:
***Builder
используются для применения конфигурации к контейнеру,***Element
содержат информацию о конфигурации и десериализуются из исходного документа.
Структура конфигурации контейнера
Элемент верхнего уровня всегда container
, он используется для хранения набора элеметов, которые распознаются и выполняются ContainerBuilder
.
Все элементы, входящие в контейнер наследуются от абстрактного класса ContainerItemElement
,
который позволяет получить текущий ContainerBuilder
и выполнить над ним какие-либо действия.
Основные элементы конфигурации контенейра
<include href='config.xml'/>
- включение конфигурации из указанного места<namespace name='My.App'/>
- добавление пространства имен для поиска типов<register type='MyGenericType{}'/>
- добавление в контейнер регистрации типаMy.App.MyGenericType`1
<factory type='IFactory{Foo}' mapTo ='MyFactory'/>
- фабрика, регистрирует свой тип, а также типFoo
<serialized />
- сериализованный экземпляр объекта, используетXmlSerializer
для десериализации<value />
- значение объекта в виде строки, используется для простых типов
Полный набор элементов, доступных для использования в контейнере определяет схема ContainerConfigurationSchema
,
разработчик может расширить контейнер совими собственными элементами зарегистрировав их в схеме.
register
О
Например, мы используем компоненту MyHttpClient
для загрузки данных
<register type="IClient" mapTo="MyHttpClient"> <property name="proxy"> <value>socks5://proxy1.my.company</value> </property> </register>
При частом использовании можно сделать описание конфигурации несколько проще, описав новый эелемент конфигурации
public class MyHttpClientElement : ContainerItemElement { public string Proxy { get; set; } public override void Visit(ContainerBuilder builder) { // создаем описание элемента var registration = new RegistrationElement { RegistrationType = "IClient", ImplementationType = "My.App.MyHttpClient", Injectors = new [] { new PropertyInjectionElement { Name = "Proxy", Value = ValueParameterElement { Value = Proxy } } } }; // применяем созданное описание к контейнеру builder.Visit(registration) } }
Регистрируем новый элемент в схеме
schema.RegisterContainerElement<MyHttpClientElement>("http");
Используем новый элемент в конфигурации
<http> <proxy>socks5://proxy1.my.company</propxy> </http>