Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Константин Салтук "Lifetime, LifetimeScope и точка расширения для точек расширения"

Константин Салтук "Lifetime, LifetimeScope и точка расширения для точек расширения"

Поговорим про способы управления временем жизни объектов в IOC-контейнерах, о понятиях Lifetime и LifetimeScope. Расскажу о нашем опыте связывания этих сущностей друг с другом, с автогенерируемыми фабриками, и как мы написали "точку расширения для точек расширения", сделав наш код более чистым и менее связанным.

DotNetRu

August 29, 2019
Tweet

More Decks by DotNetRu

Other Decks in Programming

Transcript

  1. Структура доклада • Предыстория • Чем мы занимаемся • Пример

    • Цель • Разбираемся со временем жизни инстансов в контейнерах • Lifetime как сущность • Точка расширения для точек расширения • Показываем, как решились проблемы 2
  2. Недостатки • Клиенты IMessageBroker должны сами подписываться и не забывать

    отписаться • Неявное время жизни объекта, созданного через generated-factory 15
  3. Цель • Необходим сквозной механизм, позволяющий подписывать клиентов при их

    создании и отписывать при окончании их времени жизни • Уметь контролировать время жизни созданных через фабрику инстансов 16
  4. Время жизни объекта • Для простоты будем считать, что все

    рассматриваемые нами классы реализуют IDisposable • Под временем жизни объекта (его lifetime) будем понимать промежуток времени от его создания до вызова метода Dispose() 17
  5. Бэкграунд • Бо́льшая часть сущностей создаётся контейнером • Под компонентом

    понимается любой тип, зарегистрированный в контейнере • Во все компоненты зависимости внедряются через конструктор 18
  6. Scoped 22 Scope1 Component A Component B Component C Scope2

    Component D Component E Время жизни определяется Scope’ом, в котором объект существует:
  7. InstancePerDependency Component B, C – InstancePerDependency, ExternallyOwned(?) 31 Scope Component

    A Component B Component B Component B Dispose() ? Component C Component C Component C
  8. InstancePerDependency 32 Scope 1 Component A Component B, C -

    InstancePerDependency Scope 3 Component B Component C Scope 2 Component B Component C Scope 4 Component B Component C
  9. Генерируемые фабрики, итого: • В случае InstancePerDependency время жизни сущностей

    может быть значительно больше, чем ими пользуются • В случае SingleInstance\InstancePerLifetimeScope использование фабрики в любом случае выглядит малообоснованным и ведёт себя не так, как ожидается • Использование генерируемых фабрик в таком виде приводит к неочевидным ошибкам 33
  10. Добавляем явность во время жизни • Нужно явно принимать время

    жизни объекта при его порождении через фабрику • Для этого необходима какая-то сущность, описывающая время жизни • Любой объект должен иметь возможность получить эту сущность • От времени жизни должна быть возможность создать дочернее время жизни 34
  11. Управление лайфтаймами 41 Scope 2 Scope 1 Component A Component

    B Component C Lifetime 1 Lifetime 2 Scope 3 Component B Component C Lifetime 3 Component D Component C
  12. Сквозной механизм подписки • Компоненты создаются в рамках скопа, в

    этом скопе есть инстанс Lifetime • Добавим в Lifetime метод, с помощью которого можно будет зарегистрировать action, который исполнится при завершении времени жизни • Можно автоматически подписывать и отписывать подписчиков сущностью сбоку, которая будет реагировать на создание инстансов подписчиков 42
  13. Lifetime (JB) 44 Станислав Сидристый «Шаблон Lifetime: для сложного Disposing»

    Дмитрий Иванов — Реактивное многопроцессное взаимодействие: JetBrains Rider Framework
  14. Результат 53 • Время жизни создаваемых объектов через фабрику теперь

    контролируется явно • Избавились от утечки памяти • Получили универсальный механизм для реагирования на создание и умирание объектов в рамках из жизненного цикла • Вынесли сквозную функциональность по подписке в отдельную сущность