ݺߣ

ݺߣShare a Scribd company logo
Меня зовут Илья, я занимаюсь разработкой с использованием .Net в
компании Luxoft.
efimilya@gmail.com
+7 910 900 4727
Сложность разрабатываемых систем и количество унаследованного
кода заставляют использовать инструменты и подходы.
IoC/DI в этом очень помогает.
1
IoC/DI на примере Autofac
2
Объектно-ориентированный дизайн включает
1. Создание экземпляра
2. Передача его потребителю
3. Управление временем жизни
4. Бизнес-логика
5. Очистка ненужного экземпляра
IoC-контейнер берет на себя 1, 2, 3, 5
3
1. Что такое IoC? В чем инверсия?
2. В чем преимущества IoC/DI?
3. Как это связано с буквой D из SOLID?
4. Что такое вложенные контейнеры?
5. IDisposable и IoC-контейнеры.
6. Автоматические фабрики.
4
5
Root
Root IoC-container
Без IoC/ID с IoC/ID
6
Object A Object B
ссылается
Object A Object B
Реализует
InterfaceA
ссылается
 Регистрация зависимостей в отдельных контейнерах.
 Которые могут брать зависимости из родительских контейнеров.
 Регистритрация зависимостей, параметризованных данными времени
выполнения.
 Поэтому не придется обходиться с этими данными вручную
(передавать в качестве параметров).
 Компоненты не могут иметь доступ друг к другу во время выполнения.
 Можно освободить ресурсы, вызвав Dispose вложенного контейнера.
7
Задача для фронэнда:
8
Первое решение.
 Вся регистрация в одном контейнере.
 Создание экземпляр дочернего окна явно через
конструктор.
 Передача ему нужных зависимостей (исходя из
введенных пользователем данных).
9
Плюсы:
 Мы решили задачу
 Зависимости (за исключение одной) мы разрешили
через контейнер.
10
Минусы:
 Одну из зависимостей создана через new.
 Противоречит IoC/DI.
 Не сможем использовать очистку.
 Если увеличится количество компонентов,
увеличится сложность решения.
11
Второе решение
 Использование вложенных скоупов.
 Регистрация зависимостей в отдельных
контейнерах.
 Вложенный контейнер конфигурируются на
момент выполнения.
12
Минусы:
 На первый взгляд это может показаться довольно
сложным и запутанным приемом (издержки
подхода)
13
Плюсы:
 Нет ни одного оператора new.
 Простая регистрация и разрешение зависимостей.
14
Задача усложнилась.
 Добавились новые требования.
 Стало больше компонентов.
 Контекстно-зависимые компоненты распологаются
глубоко относительно ChildWindowViewModel
 Поэтому создание ее экземпляра становится сложным.
15
Первому решению плюсов не добавилось. Минусы усугубились:
builder.Register<ChildWindowViewModelFactory>(
context =>
{
var parentContext = context.Persist();
return speaker =>
new ChildWindowViewModel(
GetSpeaker(speaker, parentContext), new ChildHeaderViewModel(
new HeaderTextFormatter(
GetFormatHeaderStrategy(speaker, parentContext)),
parentContext.Resolve<HeaderTextProvider>()));
});
16
 Второе решение не усложнилось
 Добавилась всего-лишь регистрация новых компонентов
17
Задача для бекэнда:
 Обслужить запрос пользователя.
 А именно: загрузить исходные данные.
 На их основе произвести вычисления.
18
Первое решение.
 Регистрация всех компонентов в одном
контейнере.
 Передача зависимостей через параметры методов.
19
Плюсы:
 Задача решена.
 Выглядит несложно.
20
Минусы:
 Приходится часто передавать параметры методам.
public int Calculate(int customerId, int programId, string operationName)
{
var customer = _customerRepository.Get(customerId);
var program = _programRepository.Get(programId);
var operation = _operationRepository.Get(operationName);
return _firstStepAggregator.Aggregate(customer, program, operation) +
_secondStepAggregator.Aggregate(customer, program, operation);
}
public int Aggregate(Customer customer, Program program, Operation operation)
{
return (_customerHandler.Handle(customer) +
_programHandler.Handle(program) +
_operationHandler.Handle(operation)) * _globalServiceData.Value;
}
21
Второе решение
 Использовать вложенные контейнеры.
 Контейнер занимается передачей зависимостей.
22
Минусы
 Регистрация чуть сложнее (издержки подхода)
23
Плюсы:
 Данные, которые мы передавали в качестве параметров,
теперь зарегестрированы в контейнере и получать к ним
доступ очень просто.
 Методы стали намного проще по сигнатуре.
public int Calculate()
{
return _firstStepAggregator.Aggregate() +
_secondStepAggregator.Aggregate();
}
public int Aggregate()
{
return (_customerHandler.Handle() +
_programHandler.Handle() +
_operationHandler.Handle()) * _globalServiceData.Value;
}
24
 Порой нужна очистка.
 Контейнер умеет вызывать Dispose() зависимостей.
 Удобно использоватьCompositeDisposable и
Disposable<T>
25
Disposable<T>
принимает два параметра:
 T value
 Action disposeAction
26
CompositeDisposable
 Контейнер для элементов IDisposable.
 Очистка нескольких компонентов за раз.
 Удобно, например, для отписки от событий.
27
 Func<int, string, … ,T>
 Создание экземпляров, которые на вход
принимают загерестрированные зависимости, а
также произвольные параметры.
 Экземпляр создан через контейнер, а значит мы
получаем все преимущества контейнера (передача
зависимостей, управление временем жизни и
очистка).
28
 IoC/DI делает часть работы за нас.
 Помогает упростить объектно-ориентированный
дизайн.
 Autofac поддерживает вложенные контейнеры.
 А также автоматические фабрики.
29
 Книга Марка Симана - внедрение зависимостей в .net
 Документация Autofac
 Исходный код презентации
 Статья Удобное создание Composition Root с помощью
Autofac
 Статья Самая простая и надежная реализация Статья шаблона
проектирования Dispose
 Статья Disposable без границ
30

More Related Content

Илья Ефимов «IoC/DI на примере Autofac»

  • 1. Меня зовут Илья, я занимаюсь разработкой с использованием .Net в компании Luxoft. efimilya@gmail.com +7 910 900 4727 Сложность разрабатываемых систем и количество унаследованного кода заставляют использовать инструменты и подходы. IoC/DI в этом очень помогает. 1
  • 3. Объектно-ориентированный дизайн включает 1. Создание экземпляра 2. Передача его потребителю 3. Управление временем жизни 4. Бизнес-логика 5. Очистка ненужного экземпляра IoC-контейнер берет на себя 1, 2, 3, 5 3
  • 4. 1. Что такое IoC? В чем инверсия? 2. В чем преимущества IoC/DI? 3. Как это связано с буквой D из SOLID? 4. Что такое вложенные контейнеры? 5. IDisposable и IoC-контейнеры. 6. Автоматические фабрики. 4
  • 6. 6 Object A Object B ссылается Object A Object B Реализует InterfaceA ссылается
  • 7.  Регистрация зависимостей в отдельных контейнерах.  Которые могут брать зависимости из родительских контейнеров.  Регистритрация зависимостей, параметризованных данными времени выполнения.  Поэтому не придется обходиться с этими данными вручную (передавать в качестве параметров).  Компоненты не могут иметь доступ друг к другу во время выполнения.  Можно освободить ресурсы, вызвав Dispose вложенного контейнера. 7
  • 9. Первое решение.  Вся регистрация в одном контейнере.  Создание экземпляр дочернего окна явно через конструктор.  Передача ему нужных зависимостей (исходя из введенных пользователем данных). 9
  • 10. Плюсы:  Мы решили задачу  Зависимости (за исключение одной) мы разрешили через контейнер. 10
  • 11. Минусы:  Одну из зависимостей создана через new.  Противоречит IoC/DI.  Не сможем использовать очистку.  Если увеличится количество компонентов, увеличится сложность решения. 11
  • 12. Второе решение  Использование вложенных скоупов.  Регистрация зависимостей в отдельных контейнерах.  Вложенный контейнер конфигурируются на момент выполнения. 12
  • 13. Минусы:  На первый взгляд это может показаться довольно сложным и запутанным приемом (издержки подхода) 13
  • 14. Плюсы:  Нет ни одного оператора new.  Простая регистрация и разрешение зависимостей. 14
  • 15. Задача усложнилась.  Добавились новые требования.  Стало больше компонентов.  Контекстно-зависимые компоненты распологаются глубоко относительно ChildWindowViewModel  Поэтому создание ее экземпляра становится сложным. 15
  • 16. Первому решению плюсов не добавилось. Минусы усугубились: builder.Register<ChildWindowViewModelFactory>( context => { var parentContext = context.Persist(); return speaker => new ChildWindowViewModel( GetSpeaker(speaker, parentContext), new ChildHeaderViewModel( new HeaderTextFormatter( GetFormatHeaderStrategy(speaker, parentContext)), parentContext.Resolve<HeaderTextProvider>())); }); 16
  • 17.  Второе решение не усложнилось  Добавилась всего-лишь регистрация новых компонентов 17
  • 18. Задача для бекэнда:  Обслужить запрос пользователя.  А именно: загрузить исходные данные.  На их основе произвести вычисления. 18
  • 19. Первое решение.  Регистрация всех компонентов в одном контейнере.  Передача зависимостей через параметры методов. 19
  • 20. Плюсы:  Задача решена.  Выглядит несложно. 20
  • 21. Минусы:  Приходится часто передавать параметры методам. public int Calculate(int customerId, int programId, string operationName) { var customer = _customerRepository.Get(customerId); var program = _programRepository.Get(programId); var operation = _operationRepository.Get(operationName); return _firstStepAggregator.Aggregate(customer, program, operation) + _secondStepAggregator.Aggregate(customer, program, operation); } public int Aggregate(Customer customer, Program program, Operation operation) { return (_customerHandler.Handle(customer) + _programHandler.Handle(program) + _operationHandler.Handle(operation)) * _globalServiceData.Value; } 21
  • 22. Второе решение  Использовать вложенные контейнеры.  Контейнер занимается передачей зависимостей. 22
  • 23. Минусы  Регистрация чуть сложнее (издержки подхода) 23
  • 24. Плюсы:  Данные, которые мы передавали в качестве параметров, теперь зарегестрированы в контейнере и получать к ним доступ очень просто.  Методы стали намного проще по сигнатуре. public int Calculate() { return _firstStepAggregator.Aggregate() + _secondStepAggregator.Aggregate(); } public int Aggregate() { return (_customerHandler.Handle() + _programHandler.Handle() + _operationHandler.Handle()) * _globalServiceData.Value; } 24
  • 25.  Порой нужна очистка.  Контейнер умеет вызывать Dispose() зависимостей.  Удобно использоватьCompositeDisposable и Disposable<T> 25
  • 27. CompositeDisposable  Контейнер для элементов IDisposable.  Очистка нескольких компонентов за раз.  Удобно, например, для отписки от событий. 27
  • 28.  Func<int, string, … ,T>  Создание экземпляров, которые на вход принимают загерестрированные зависимости, а также произвольные параметры.  Экземпляр создан через контейнер, а значит мы получаем все преимущества контейнера (передача зависимостей, управление временем жизни и очистка). 28
  • 29.  IoC/DI делает часть работы за нас.  Помогает упростить объектно-ориентированный дизайн.  Autofac поддерживает вложенные контейнеры.  А также автоматические фабрики. 29
  • 30.  Книга Марка Симана - внедрение зависимостей в .net  Документация Autofac  Исходный код презентации  Статья Удобное создание Composition Root с помощью Autofac  Статья Самая простая и надежная реализация Статья шаблона проектирования Dispose  Статья Disposable без границ 30