Внедрение зависимости (Dependency Injection — DI) означает передачу (внедрение) одной или более зависимости какому-либо объекту (клиенту, компоненту) таким образом, что после внедрения эта зависимость становится частью состояния объекта. Это немного напоминает паттерн проектирования Стратегия, с той лишь разницей, что стратегия задаётся лишь однажды — в конструкторе. DI позволяет создавать более слабо-связанную архитектуру приложения, которая лучше поддаётся поддержке и тестированию.
Итак, ещё раз плюсы:
Boost.DI это библиотека для реализации внедрения зависимости в С++. Для её использования нужно лишь включить в свой код один заголовочный файл. Цель библиотеки — упростить создание объектов с помощью автоматического внедрения зависимостей:

А вообще-то всё, что вам необходимо для работы с библиотекой, этой файл di.hpp
Давайте предположим, что все примеры ниже включают boost/di.hpp и определяют пространство имён di как алиас boost::di.
Примеры
Ещё примеры
Примеры
Ещё примеры
Примеры
Примеры
Ещё примеры

Примеры
Примеры
Примеры
Ещё примеры
Окружение
Пример
Окружение
Легенда



Лицензия: Boost Software License, Version 1.0
Нюанс: библиотека пока не входит в Boost, а лишь находится в "инкубаторе".
Источник: habrahabr.ru
Итак, ещё раз плюсы:
- Уменьшает связность компонент (отделяет бизнес-логику от создания объекта)
- Позволяет писать более поддерживаемый код (в одни и те же объекты мы легко можем внедрять разные зависимости)
- Позволяет писать более тестируемый код (мы можем легче использовать стабы и моки)
| Без внедрения зависимости | С внедрением зависимости |
|---|---|
Boost.DI это библиотека для реализации внедрения зависимости в С++. Для её использования нужно лишь включить в свой код один заголовочный файл. Цель библиотеки — упростить создание объектов с помощью автоматического внедрения зависимостей:
- Уменьшение количества «узких мест» в коде — никаких лишних фабрик, никакого создания объектов лишь в определённом порядке
- Упрощение поддержки кода — изменение сигнатуры конструктора не повлияет на конфигурацию DI
- Упрощение тестирование — автоматическая инъекция моков
- Более хороший контроль над тем, что и когда создаётся
- Лучшее понимание кода в плане иерархии объектов
| Ручное внедрение зависимости | Boost.DI |
|---|---|
Ещё раз — зачем использовать внедрение зависимости
С чего начать?
- Возьмите компилятор с поддержкой С++14 (Clang-3.4+, GCC-5.0+). Библиотека Boost не требуется
- Прочитайте этот документ
- Прочитайте учебник
- Прочитайте документацию
А вообще-то всё, что вам необходимо для работы с библиотекой, этой файл di.hpp
Давайте предположим, что все примеры ниже включают boost/di.hpp и определяют пространство имён di как алиас boost::di.
Инжектор
| Создание пустого инжектора | Тест |
|---|---|
Привязки
Примеры
Ещё примеры
| Привязка интерфейса к реализации | Тест |
|---|---|
| Привязка нескольких интерфейсов к одной реализации | Тест |
|---|---|
| Привязка типа к значению, вычисляемому на этапе компиляции | Тест |
|---|---|
| Привязка типа к значению | Тест |
|---|---|
Внедрение
Примеры
Ещё примеры
| Внедрение через обычный конструктор | Тест |
|---|---|
| Внедрение через аггрегацию | Тест |
|---|---|
| Внедрение через конструктор при наличии нескольких конструкторов (будет выбран тот, у которого наибольшее число параметров) | Тест |
|---|---|
| Внедрение через конструктор при наличии вариантов выбора (использование BOOST_DI_INJECT) | Тест |
|---|---|
| Внедрение через конструктор при наличии вариантов выбора (использование BOOST_DI_INJECT_TRAITS) | Тест |
|---|---|
| Внедрение через конструктор при наличии вариантов выбора (использование di::ctor_traits) | Тест |
|---|---|
Аннотации
Примеры
| Внедрение через аннотированные конструкторы | Тест |
|---|---|
| Внедрение через аннотированные конструкторы с использованием именованных параметров | Тест |
|---|---|
| Внедрение через аннотированные конструкторы с вынесением реализации конструктора | Тест |
|---|---|
| Внедрение через аннотированные конструкторы с использованием di::ctor_traits | Тест |
|---|---|
Области видимости
Примеры
Ещё примеры
| Вывод области видимости (по-умолчанию) | Тест |
|---|---|
| Тип | Выведенная область видимости |
|---|---|
| T | unique |
| T& | ошибка — должен быть связан как external |
| const T& | unique (временный) |
| T* | unique (передача владения) |
| const T* | unique (передача владения) |
| T&& | unique |
| unique_ptr | unique |
| shared_ptr | singleton |
| weak_ptr | singleton |
| Уникальная область видимости | Тест |
|---|---|
| Разделяемая область видимости (в пределах потока) | Тест |
|---|---|
| Синглтон (разделяем между потоками) | Тест |
|---|---|
| Область видимости сессии | Тест |
|---|---|
| Внешняя область видимости | Тест |
|---|---|
| Специальная область видимости | Тест |
|---|---|
Модули
Примеры
| Модуль | Тест |
|---|---|
| Модуль, открывающий тип | Тест |
|---|---|
| Модуль, открывающий несколько типов | Тест |
|---|---|
| Модуль открытого типа с аннотацией | Тест |
|---|---|
Провайдеры
Примеры
| «no throw»-провайдер | Тест |
|---|---|
Политики
Примеры
Ещё примеры
| Определение политик конфигурации (дамп типов) | Тест |
|---|---|
| Определение политик конфигурации (развёрнутый дамп типов) | Тест |
|---|---|
| Политика «может быть сконструирован» | Тест |
|---|---|
Производительность на рантайме
Окружение
- x86_64 Intel® Core(TM) i7-4770 CPU @ 3.40GHz GenuineIntel GNU/Linux
- clang++3.4 -O2 / gdb -batch -ex 'file ./a.out' -ex 'disassemble main'
| Создание типа без привязок | Asm x86-64 (то же, что «return 0») |
|---|---|
| Создание типа с привязкой объекта | Asm x86-64 (то же, что «return 42») |
|---|---|
| Создание именованного типа | Asm x86-64 (то же, что «return 42») |
|---|---|
| Создание привязки интерфейса к реализации | Asm x86-64 (то же, что «make_unique») |
|---|---|
| Создание привязки интерфейса через модуль | Asm x86-64 (то же, что «make_unique») |
|---|---|
| Создание привязки интерфейса через открытый модуль | Asm x86-64 цена = вызов виртуального метода |
|---|---|
Производительность на этапе компиляции
Пример
Окружение
- x86_64 Intel® Core(TM) i7-4770 CPU @ 3.40GHz GenuineIntel GNU/Linux
- clang++3.4 -O2
| Заголовочный файл Boost.DI | Время [сек] |
|---|---|
| 0.165 |
Легенда
- ctor = «голый» конструктор: c(int i, double d);
- inject = внедрение в конструктор: BOOST_DI_INJECT(c, int i, double d);
- all = все типы в модуле доступны: auto configure();
- exposed = один тип в модуле доступен: di::injector<c> configure();
- 4248897537 объектов создано
- 132 разных типа
- 10 модулей
- 1862039751439806464 объекта создано
- 200 разных типов
- 10 модулей
- 5874638529236910091 объект создан
- 310 разных типов
- 100 разных интерфейсов
- 10 модулей
Диагностические сообщения
| Создание интерфейса без привязки к реализации | Сообщение об ошибке |
|---|---|
| Неоднозначность привязки | Сообщение об ошибке |
|---|---|
| Создание объекта без привязок при политике, требующей их | Сообщение об ошибке |
|---|---|
| Неверный синтаксис аннотаций (NAMED вместо named) | Сообщение об ошибке |
|---|---|
Конфигурация
| Макрос | Описание |
|---|---|
Похожие библиотеки
Лицензия: Boost Software License, Version 1.0
Нюанс: библиотека пока не входит в Boost, а лишь находится в "инкубаторе".
Источник: habrahabr.ru
Комментариев нет:
Отправить комментарий