##// END OF EJS Templates
Fixed promise rejection when there is not specified error handler in the reaction....
Fixed promise rejection when there is not specified error handler in the reaction. FIXED SPELLING IN THE XML CONTAINER CONFIGURATION signleton->singleton Code cleanup Update tests make them working on dotnet core

File last commit:

r284:bcb6c16f6fed v3
r295:28af686e24f7 default
Show More
XmlConfiguration.ru.md
112 lines | 7.2 KiB | text/x-minidsrc | MarkdownLexer

XML Конфигурация IoC контейнера

Библиоетка создавалась для загрузки и применения конфигурации к IoC контейнеру, она не предназначена для конфигурирования контейнера во время выполнения, большинство контейнеров уже обладают данным функционалом.

На данный момент поддерживается единственный вид контейнера - Unity Container

Unity уже обладает средствами загрузки конфигурации из XML, данная библиотека реализует аналогичный функционал, кроме того, позволяет решать следующие задачи:

  • Конфигурация является простым Xml документом, который можно получить из любого источика и не ограничивается .config файлами приложения
  • Включение существующе конфигурации <include href='config.xml'/> в текущую
  • Поддержка сериализованных объектов в качестве регистраций сервисов и параметров
  • Поддержка специфиакции генериков любой вложенности, например 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 и выполнить над ним какие-либо действия.

Основные элементы конфигурации контенейра

  • <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>