276
|
1 # XML Конфигурация IoC контейнера
|
|
2
|
|
3 Данная библиоетка создавалась для загрузки и применения конфигурации к IoC контейнеру, она не предназначена для конфигурирования
|
|
4 контейнера во время выполнения, большинство контейнеров уже обладают данным функционалом.
|
|
5
|
|
6 На данный момент поддерживается единственный вид контейнера - [Unity Container](https://unitycontainer.github.io/)
|
|
7
|
|
8 Unity уже обладает средствами загрузки конфигурации из XML, данная библиотека позволяет решать следующие задачи
|
|
9
|
|
10 - Конфигурация является простым Xml документом, который можно получить из любого источика и не ограничивается `.config` файлами приложения
|
|
11 - Включение существующе конфигурации `<include href='config.xml'/>` в текущую
|
|
12 - Поддержка сериализованных объектов в качестве регистраций сервисов и параметров
|
|
13 - Описание зависимостей может быть расширено собсвтенными элементами с произвольной структурой
|
|
14 - Поддержка специфиакции генериков любой вложенности `Dictionary{Foo,Bar{Int32}}`
|
|
15
|
|
16 ## Общая архитектура
|
|
17
|
|
18 `Implab.ServiceHost.Unity` содержит в себе классы для загрузки и применения XML конфигурации к IoC контейнеру, в частности к Unity.
|
|
19
|
|
20 1. Настраивается схема `ContainerConfigurationSchema`
|
|
21 2. Загружается документ и десереализуется в виде `ContainerElement`
|
|
22 3. Создается `ContainerBuilder` при помощи которого применяются настройки из `ContainerElement`
|
|
23
|
|
24 `ContainerConfigurationSchema` - определяет элементы которые могут быть использованы в конфигурации контейнера, предоставляет настроенный `XmlSerializer`.
|
|
25
|
|
26 `ContainerBuilder` - основной класс, который используется для применения конфигурации к контейнеру, добавляет записи регистрации сервисов.
|
|
27
|
|
28 `ContainerElement` - Корневой элемент конфигурации, который загружается из документа.
|
|
29
|
|
30 Классы заканчивающиеся словом `Builder` используются для применения конфигурации к контейнеру,
|
|
31 классы заканчивающиеся на `Element` содержат информацию о конфигурации и десериализуются из исходного документа.
|
|
32
|
|
33 ## Структура конфигурации контейнера
|
|
34
|
|
35 Элемент верхнего уровня всегда `ContainerElemnt`, он используется для хранения набора элеметов, которые распознаются и выполняются `ContainerBuilder`.
|
|
36
|
|
37 Все элементы, входящие в контейнер наследуются от абстрактного класса `ContainerItemElement`,
|
|
38 который позволяет получить текущий `ContainerBuilder` и выполнить над ним какие-либо действия.
|
|
39
|
|
40 Примерами элементов контейнера могут быть
|
|
41
|
|
42 - `<include href='config.xml'/>` - включение конфигурации из указанного места
|
|
43 - `<namespace name='My.App'/>` - добавление пространства имен для поиска типов
|
|
44 - `<register type='MyGenericType{}'/>` - добавление в контейнер регистрации типа ``My.App.MyGenericType`1``
|
|
45
|
|
46 Полный набор элементов, доступных для использования в контейнере определяет схема `ContainerConfigurationSchema`,
|
|
47 разработчик может расширить контейнер совими собственными элементами зарегистрировав их в схеме.
|
|
48
|
|
49 Например, мы используем компоненту `MyHttpClient` для загрузки данных
|
|
50
|
|
51 ```xml
|
|
52 <register type="IClient" mapTo="MyHttpClient">
|
|
53 <property name="proxy">
|
|
54 <value>socks5://proxy1.my.company</value>
|
|
55 </property>
|
|
56 </register>
|
|
57 ```
|
|
58
|
|
59 При частом использовании можно сделать описание конфигурации несколько проще,
|
|
60 описав новый эелемент конфигурации
|
|
61
|
|
62 ```csharp
|
|
63 public class MyHttpClientElement : ContainerItemElement {
|
|
64
|
|
65 public string Proxy { get; set; }
|
|
66
|
|
67 public override void Visit(ContainerBuilder builder) {
|
|
68 // создаем описание элемента
|
|
69 var registration = new RegistrationElement {
|
|
70 RegistrationType = "IClient",
|
|
71 ImplementationType = "My.App.MyHttpClient",
|
|
72 Injectors = new [] {
|
|
73 new PropertyInjectionElement {
|
|
74 Name = "Proxy",
|
|
75 Value = ValueParameterElement {
|
|
76 Value = Proxy
|
|
77 }
|
|
78 }
|
|
79 }
|
|
80 };
|
|
81
|
|
82 // применяем созданное описание к контейнеру
|
|
83 builder.Visit(registration)
|
|
84 }
|
|
85 }
|
|
86 ```
|
|
87
|
|
88 Регистрируем новый элемент в схеме
|
|
89
|
|
90 ```csharp
|
|
91 schema.RegisterContainerElement<MyHttpClientElement>("http");
|
|
92 ```
|
|
93
|
|
94 Используем новый элемент в конфигурации
|
|
95
|
|
96 ```xml
|
|
97 <http>
|
|
98 <proxy>socks5://proxy1.my.company</propxy>
|
|
99 </http>
|
|
100 ``` |