# XML Конфигурация IoC контейнера
Библиоетка создавалась для загрузки и применения конфигурации к IoC контейнеру, она не предназначена для конфигурирования
контейнера во время выполнения, большинство контейнеров уже обладают данным функционалом.
На данный момент поддерживается единственный вид контейнера - [Unity Container](https://unitycontainer.github.io/)
Unity уже обладает средствами загрузки конфигурации из XML, данная библиотека реализует аналогичный функционал, кроме того, позволяет решать следующие задачи:
- Конфигурация является простым Xml документом, который можно получить из любого источика и не ограничивается `.config` файлами приложения
- Включение существующе конфигурации `` в текущую
- Поддержка сериализованных объектов в качестве регистраций сервисов и параметров
- Поддержка специфиакции генериков любой вложенности, например `Dictionary{Foo,Bar{Int32}}`
- Поддержка фабрик в XML конфигурации
- Расширение схемы XML конфигурации собственными элементами
## Общая архитектура
Пространство имен `Implab.ServiceHost.Unity` содержит в себе классы для загрузки и применения XML конфигурации к IoC контейнеру.
Применение конфигурации к контейнеру состоит из следующих основных шагов:
1. Настраивается схема `ContainerConfigurationSchema` XML конфигурации контейнера
2. Загружается документ и десереализуется в виде `ContainerElement`
3. Создается `ContainerBuilder` при помощи которого применяются настройки из `ContainerElement` к контейнеру
Схема `ContainerConfigurationSchema` определяет элементы документа, которые могут быть использованы в конфигурации контейнера, позволяет создать `XmlSerializer`, который используется для загрузки конфигурации.
`ContainerBuilder` - основной класс, который используется для применения конфигурации к контейнеру, он добавляет записи регистрации сервисов из конфигурации в контейнер.
`ContainerElement` - Конфигурация контейнера, которая загружается из документа, состоит из директив для `ContainerBuilder`, а также из записей регистрации сервисов.
В библиотеки приняты следующие правила именования классов:
- `***Builder` используются для применения конфигурации к контейнеру,
- `***Element` содержат информацию о конфигурации и десериализуются из исходного документа.
## Структура конфигурации контейнера
Элемент верхнего уровня всегда `container`, он используется для хранения набора элеметов, которые распознаются и выполняются `ContainerBuilder`.
Все элементы, входящие в контейнер наследуются от абстрактного класса `ContainerItemElement`,
который позволяет получить текущий `ContainerBuilder` и выполнить над ним какие-либо действия.
Основные элементы конфигурации контенейра
- `` - включение конфигурации из указанного места
- `` - добавление пространства имен для поиска типов
- `` - добавление в контейнер регистрации типа ``My.App.MyGenericType`1``
- `` - фабрика, регистрирует свой тип, а также тип `Foo`
- `` - сериализованный экземпляр объекта, использует `XmlSerializer` для десериализации
- `` - значение объекта в виде строки, используется для простых типов
Полный набор элементов, доступных для использования в контейнере определяет схема `ContainerConfigurationSchema`,
разработчик может расширить контейнер совими собственными элементами зарегистрировав их в схеме.
### register
О
Например, мы используем компоненту `MyHttpClient` для загрузки данных
```xml
socks5://proxy1.my.company
```
При частом использовании можно сделать описание конфигурации несколько проще,
описав новый эелемент конфигурации
```csharp
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)
}
}
```
Регистрируем новый элемент в схеме
```csharp
schema.RegisterContainerElement("http");
```
Используем новый элемент в конфигурации
```xml
socks5://proxy1.my.company
```