SlideShare a Scribd company logo
Deep dive in
Magento DI
Maksym Grom
Немного обо мне
Максим Гром Tech Lead in ZFort
3 года с Magento 2
6 лет преподавал в ХАИ
MailMaximGrom@gmail.com
Веду 2 канала на youtube:
Maksym Grom / WebDev. GromMax
47
Что полезного?
План доклада
Наследование ∉ киты ООП
Композиция - мейнстрим (не только в M2)
Private > Protected
Interface > Abstract Class
VirtualType, Plugin > Rewrite, Preference
Что полезного? 49
Увидеть новый уровень SOLIDности кода
S - один класс одна задача
O - все можно расширить
L - чистый конструктор
I - композиция интерфейсов - мейнстрим
D - проси интерфейс, а не реализацию
Что полезного? 50
DI в M2
Немного основ
DI это когда
Что дает DI для M2?
● Все объекты создаются из Inversion of Control
(IoC) Container
● IoC Container владеет конфигурацией каждого
класса в системе
● Объект просит зависимость через конструктор,
а IoC решает что туда передать
52
DI недостатки
● Создание дерева зависимостей при создании объекта
● Медленное создание объекта при медленном
конструкторе в зависимости
● Накладные расходы из-за рефлексии
● Обслуживание конфигурации (У M2 все есть -> xml)
Что дает DI для M2? 53
ObjectManager - IoC
Что дает DI для M2? 54
Декларативная xml схема композиции
Что дает DI для M2? 55
xsi:type
Простые типы: string, boolean, number
Опциональный параметр: null
Что дает DI для M2? 56
xsi:type =”const”
Внедрит константу класса как параметр
Что дает DI для M2? 57
xsi:type =”array”
Позволяет строить дерево параметров
Что дает DI для M2? 58
xsi:type =”init_parameter”
Внедрит $_SERVER[$key]
Что дает DI для M2? 59
xsi:type =”object”
Создаст shared инстанс класса и внедрит
Что дает DI для M2? 60
Биндинг интерфейсов к реализациям (SOLID)
Что дает DI для M2? 61
Перехват публичных методов. Plugins (SOLID)
Что дает DI для M2? 62
Запуск приложения с разными настройками
Initial
app/etc/di.xml
Global
[vendor]/[module]/etc/di.xml
Area
[vendor]/[module]/etc/[area]/di.xml
frontend, adminhtml, webapi_rest,
webapi_soap, crontab, graphql
Что дает DI для M2? 63
Как работает DI
Немного основ
Bootstrap App -> app/etc/di.xml
Как работает DI?
Загрузить initial di.xml
(app/etc/di.xml)
ObjectManager::configure($di)
MagentoFrameworkObjectManagerConfigConfig
Подготовка di в php
Создать App
65
Решить для какой area этот процесс
bin/magento http
/rest
Di
global
Di
global
cron:run
Di
crontab
Area
crontab
cli /?wsdl /admin /
Di
webapi_rest
Area
webapi_rest
Di
frontend
Area
frontend
Di
adminhtml
Area
adminhtml
Di
webapi_soap
Area
webapi_soap
Cron Job Rest Service Soap Service Action
Как работает DI? 66
ObjectManager -> create or get (Shared)
create($type, $arguments) get($type)
Cached?
Create type
Return object
Cache type
getPreference
true
false
Как работает DI? 67
Create type
create($type, $args)
$params = resolveParams($type)
$params === null
return new $type()
$args = resolveArguments($params, $args)
return create($type, $args)
Если аргумент object то создаем
через ObjectManager
Если shared то через get,
иначе через create (рекурсия)
Как работает DI? 68
Результат в M2. Single Public Method Classes
Тип класса Публичные методы
Actions dispatch
Factory create
Observer execute
Service execute
Repository* get, getById, save, getList, delete
Как работает DI? 69
Результат в M2
● Запускаются все конструкторы*, потом
методы
● Медленный конструктор - плохо
● Data Transfer Object (DTO) без
конструктора
Как работает DI? 70
Ограничения DI
ObjectManager::configure
Ограничения MagentoFrameworkObjectManagerConfigConfig
array_replace переопределяет параметры
Ограничения DI
Start from class config
trim(class, ‘’) isset(args[class])
Обновить аргументы через array_replace
true
72
Задача, добавить грид в админку
ProjectBlogetcadminhtmldi.xml
В любом гриде в админке ошибка
Невозможно создать [name]_data_source
В чем проблема?
Ограничения DI 73
Задача, добавить грид в админку
ProjectBlogetcadminhtmldi.xml
CollectionFactory
Собирается как global di.xml
Ограничения DI 74
Ограничения MagentoFrameworkObjectManagerConfigConfig
MyClass === MyClass
issue #21193 #21796
Start from class config
trim(class, ‘’) isset(args[class])
Обновить аргументы через array_replace
true
Ограничения DI 75
Задача, добавить грид в админку
ProjectBlogetcdi.xml
Не используйте слеш перед именем
класса!
Ограничения DI 76
Virtual Type
Жизнь без
наследования
Переиспользуй классы
MagentoFrameworkPricingPricePool
Virtual type 78
Регистрируй в DI новый тип
Заменяй аргументы конструктора
Virtual type 79
Внедряй новый тип на место старого
Virtual type 80
Или получай через ObjectManager
Или внедряй как Block
Или внедряй как ViewModel
Virtual type 81
Примечание
● VirtualType может быть создан из VirtualType
● Параметры конструктора type и virtualType
склеиваются через array_replace
● Для класса типа Pool нужно обеспечить
возможность склейки типов
Virtual type 82
Pool, склеиваем массив в конструкторе Virtual type 83
Задача
● Загрузить список продуктов
● Продукты конкретной категории
● Если категория anchor, то загрузить продукты
дочерних категорий
Virtual type 84
Наши пожелания
● Создать как можно меньше кода
● Не создавать новые API сервисы
● В идеале использовать
MagentoCatalogApiProductRepositoryInterface
● Не использовать ProductCollection как
зависимость в своем коде
Virtual type 85
Посмотрим что есть в ProductRepository Virtual type 86
Изучим что за ProductCollectionProcessor
Фильтры - то что нужно
Virtual type 87
FilterProcessor
Ура! Есть место и пример класса для
внедрения
Virtual type 88
Внедряем свой класс для фильтра
Ключ важен!
Virtual type 89
Осталось реализовать фильтр
$collection умеет делать такую фильтрацию
Virtual type 90
Можно пользоваться
Virtual type 91
VirtualType. Вывод
● Это экземпляр базового класса
● Идеально для композиции
● Массивы в конструкторе замещаются
полностью
● Можно создать через ObjectManager
● VirtualType можно сделать из VirtualType
Virtual type 92
Plugins
Plugin регистрируется в di.xml
Перехватывает любой публичный метод
Класс плагина не нужно наследовать
Plugin это shared объект
Plugins 94
Как DI решает кого плагинить (dev mode)
Начало
Сканировать методы
before[MetodName]
around[...], after[...]
Есть плагины в
цепочке
Завершить для этого класса
Вычислить цепочку родителей
(классы, интерфейсы)
Генерировать Interceptor
Подготовить конфиг
очередности вызовов для
методов
Этот
класс
Final?
Сортировать плагины
Подменить класс на Interceptor
true
false true
false
Plugins 95
Очередность вызова плагинов
Plugins 96
Around может прерывать цепочку вызовов Plugins 97
Plugins не работают для
Static method
- Должен быть создан класс через ObjectManager
Private method
- Не наследуются в Interceptor
Protected method
- Нарушение SOLID принципов (use preference)
VirtualType - новый объект, а не класс
- Плагинится класс
Plugins 98
Plugins. Вывод
● Используй на классы другого модуля
● Делай stateless plugin - shared object
● Before plugin для подмены входных параметров
● After plugin для подмены результата
● Around plugin > preference
● Используй на Interface > Class
Plugins 99
Factory
Задача подготовить массив моделей из CSV
Модель другого модуля с интерфейсом
Интерфейс с пометкой @api, модель нет
● Через конструктор можно получить только
один объект или shared
● Через new нельзя создавать интерфейсы
● Классы без @api могут быть удалены - проблема
обновлений
Factory. Набрать массив интерфейсных моделей 101
Magento создаст фабрику автоматически
по наличию постфикса Factory
Factory. Набрать массив интерфейсных моделей 102
Factory без хардкода
Factory. Набрать массив интерфейсных моделей 103
Factory. Вывод
● Нужно создавать объекты? Используй
Factory
● Factory - пример класса без хардкода
● Генерация Factory гарантирует
однотипность этого подхода
Factory 104
Proxy
Задача сделать CLI, работающую с frontend area
И загрузить продукт со SKU “Test”
Vendor/Module/etc/di.xml
Proxy. CLI, загрузка продукта SKU TEST 106
Добавим зависимости
Proxy. CLI, загрузка продукта SKU TEST 107
Инициализируем area и di в начале метода execute
1. Активирует area для специальных случаев (загрузка
сессии)
2. Подключает DI для area
Proxy. CLI, загрузка продукта SKU TEST 108
Проблема. ProductRepository создан в конструкторе
1. Обращение к БД в конструкторе CLI
2. Создание класса до готовности DI (1-2-3 -> 2-1-3)
Proxy. CLI, загрузка продукта SKU TEST 109
Подменяем класс на Proxy
Proxy - отложенная загрузка класса. При первом запросе к
proxy объекту будет создан исходный объект.
Назначайте Proxy только через di.xml
Proxy. CLI, загрузка продукта SKU TEST 110
Integration Test
Начало
Очистка тестовой
DB
bin/magento setup:upgrade
Запуск тестов на новой БД
Создает ConsoleListInterface
Создает все объекты команд
Для каждой команды строится
дерево зависимостей
-Запрос к БД ломает наполнение БД
-ResourceModel делает запрос к БД
-Repository внедряет ResourceModel
Proxy 111
Repository 1-3 ломает запуск тестов
ConsoleListInterface
CLI #1
CLI #2 CLI #3
CLI #4
Service #1
Repository #2
Repository #3Service #2
Repository #1 Service #3
Proxy 112
Proxy обрывает дерево зависимостей
ConsoleListInterface
CLI #1
CLI #2 CLI #3
CLI #4
Service #1
Repository #2
Repository #3Service #2
Repository #1 Service #3
Proxy 113
S#2 -> R#2 ломает тесты, добавим прокси
ConsoleListInterface
CLI #1
CLI #2 CLI #3
CLI #4
Service #1
Repository #2
Repository #3Service #2
Repository #1 Service #3
Proxy 114
S#1 -> R#1 новая связь, ломает тесты
ConsoleListInterface
CLI #1
CLI #2 CLI #3
CLI #4
Service #1
Repository #2
Repository #3Service #2
Repository #1 Service #3
Proxy 115
S#1 -> R#1 опять PROXY :(. Может есть выход?
ConsoleListInterface
CLI #1
CLI #2 CLI #3
CLI #4
Service #1
Repository #2
Repository #3Service #2
Repository #1 Service #3
Proxy 116
Внедряй на 1 CLI 1 Service + Proxy
ConsoleListInterface
CLI #1
CLI #2 CLI #3 CLI #4
Service #1
Repository #2
Repository #3Service #2
Repository #1 Service #3
CLI Service #2CLI Service #1
CLI Service #4
CLI Service #3
Proxy 117
Proxy. Вывод
● Всегда проксируй зависимости CLI
● Минимизируй количество зависимостей CLI
● Используй Proxy для медленного
конструктора
Proxy 118
Выводы
Выводы в целом
● Создавай объекты через Factory
● Медленный конструктор - плохо (Proxy)
● Используй композицию вместо наследования
● Используй чужой код через VirtualType
● Инициализируй сервис через конструктор
● Расширяй сервисы через Plugin
120
Что почитать
- https://devdocs.magento.com/guides/v2.3/extension-dev-guide/build/di-xml-file.html
- https://devdocs.magento.com/guides/v2.3/extension-dev-guide/factories.html
- https://devdocs.magento.com/guides/v2.3/extension-dev-guide/proxies.html
- https://devdocs.magento.com/guides/v2.3/extension-dev-guide/code-generation.html
- https://alanstorm.com/magento_2_object_manager_virtual_types/
- https://devdocs.magento.com/guides/v2.3/extension-dev-guide/attributes.html
- https://devdocs.magento.com/guides/v2.3/extension-dev-guide/searching-with-repositories.html
121
Q&A

More Related Content

ODP
Behavior Driven Development
KEY
Testing RIA with Selenium
PPTX
Модульная структура
PPTX
Как приручить реактивное программирование в XAML приложениях
PPTX
Как приручить реактивное программирование
PPTX
Эволюция к Behavior Driven Development на примере популярного фреймворка JBehave
PPTX
Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...
Behavior Driven Development
Testing RIA with Selenium
Модульная структура
Как приручить реактивное программирование в XAML приложениях
Как приручить реактивное программирование
Эволюция к Behavior Driven Development на примере популярного фреймворка JBehave
Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...

What's hot (20)

PDF
C++ STL & Qt. Занятие 05.
PDF
C++ STL & Qt. Занятие 10.
PPTX
Java Core. Lecture# 5. Concurrency.
PDF
C++ STL & Qt. Занятие 04.
PPTX
Практика использования Dependency Injection
PPTX
Bytecode
PDF
C++ STL & Qt. Занятие 03.
PDF
Java осень 2014 занятие 3
PPTX
. Kotlin для Автоматизации тестирования – первые впечатления
PPTX
Виктор Стрелков - Jabber как инструмент разработчика
PDF
C++ STL & Qt. Занятие 02.
PPTX
Java Core. Lecture# 3. Part# 3. Multithreading.
PDF
09 - Java. Тестирование Java-программ
PDF
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
PDF
C++ STL & Qt. Занятие 01.
PPTX
Java Core. Lecture# 3. Part# 2. Exceptions.
PPTX
Legacy: как победить в гонке (Joker)
PPT
DI and Zend Framework (ZFConf2011)
PPTX
Сидристый Станислав: Паттерны и антипаттерны BDD
PDF
03 - Java. Объекты, классы и пакеты в Java
C++ STL & Qt. Занятие 05.
C++ STL & Qt. Занятие 10.
Java Core. Lecture# 5. Concurrency.
C++ STL & Qt. Занятие 04.
Практика использования Dependency Injection
Bytecode
C++ STL & Qt. Занятие 03.
Java осень 2014 занятие 3
. Kotlin для Автоматизации тестирования – первые впечатления
Виктор Стрелков - Jabber как инструмент разработчика
C++ STL & Qt. Занятие 02.
Java Core. Lecture# 3. Part# 3. Multithreading.
09 - Java. Тестирование Java-программ
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
C++ STL & Qt. Занятие 01.
Java Core. Lecture# 3. Part# 2. Exceptions.
Legacy: как победить в гонке (Joker)
DI and Zend Framework (ZFConf2011)
Сидристый Станислав: Паттерны и антипаттерны BDD
03 - Java. Объекты, классы и пакеты в Java
Ad

Similar to Deep Dive in Magento DI (20)

PPTX
История одной трансформации: как Magento 1 разработчику быстро переориентиров...
PPTX
Применение компонент-ориентированной архитектуры для написания Magento Extens...
PPTX
Антон Капля - Meet Magento Ukraine - Кодогенератор в Magento
PDF
Magento 2. X.commerce.
PPTX
Сервис-Ориентированная Архитектура: путь от потребностей к возможностям
PPTX
Сommand Query Responsibility Segregation (CQRS) - Отделяем Мух от Котлет
PDF
Zend framework 2
PPTX
Александр Каранда - Meet Magento Ukraine - Реальность нереальных вещей
PPT
Общая архитектура Yii2
ODP
Применение DDD подхода в Symfony 2 приложении
PPT
ZFConf 2011: Гибкая архитектура Zend Framework приложений с использованием De...
PPT
Архитектура Drupal Commerce. Основы работы с Drupal Commerce
PDF
Чуть сложнее чем Singleton: аннотации, IOC, АОП
PPTX
RESTful API: Best practices, versioning, design documentation
PDF
Контейнер сервисов
PPTX
Реализация шаблонов корпоративных приложений в Magento
PDF
Гатиятов Руслан, технический директор ООО “Дроид Лабс”: “Система управления п...
PDF
Основы доменной модели
PPT
Symfony2 practice
История одной трансформации: как Magento 1 разработчику быстро переориентиров...
Применение компонент-ориентированной архитектуры для написания Magento Extens...
Антон Капля - Meet Magento Ukraine - Кодогенератор в Magento
Magento 2. X.commerce.
Сервис-Ориентированная Архитектура: путь от потребностей к возможностям
Сommand Query Responsibility Segregation (CQRS) - Отделяем Мух от Котлет
Zend framework 2
Александр Каранда - Meet Magento Ukraine - Реальность нереальных вещей
Общая архитектура Yii2
Применение DDD подхода в Symfony 2 приложении
ZFConf 2011: Гибкая архитектура Zend Framework приложений с использованием De...
Архитектура Drupal Commerce. Основы работы с Drupal Commerce
Чуть сложнее чем Singleton: аннотации, IOC, АОП
RESTful API: Best practices, versioning, design documentation
Контейнер сервисов
Реализация шаблонов корпоративных приложений в Magento
Гатиятов Руслан, технический директор ООО “Дроид Лабс”: “Система управления п...
Основы доменной модели
Symfony2 practice
Ad

More from Magecom UK Limited (20)

PPTX
Magento Meetup #12. Alex Shkurko.pptx
PPTX
Magento Meetup #12 Anastasiia Bondar
PPTX
Magento Meetup #12 Vlad Opukhlyi
PPTX
Google Page Insights and Magento 2 — Sergey Nezbritskiy | Magento Meetup Onli...
PPTX
Magento NodeJS Microservices — Yegor Shytikov | Magento Meetup Online #11
PPTX
Magento enhanced media gallery - Alexander Shkurko
PPTX
7 ошибок одного Black Friday - Влад Опухлый
PPTX
Magento & Cloud - Korostelov Avexey
PDF
Making the Magento 2 Javascript Loading Great Again - Robin van Raan
PDF
From Repositories to Commands - Alexander Shkurko
PPTX
Advanced GIT or How to Change the History
PPTX
MSI In-Store Pickup Функционал & сложности
PPTX
Adobe Stock Integration community project
PDF
Proof of Concept for Magento 2 Projects: Occamo’s Razor
PPTX
Что нужно знать девелоперу о SEO на этапе проектирования сайта
PPTX
Magento-сертификация: инструкция по применению и как это было
PPTX
Experience in Magento Community Projects
PPTX
UI components: synergy of backend and frontend
PPTX
MSI - Reservation Challenges with 3rd-party Systems
PPTX
Business wants what?!
Magento Meetup #12. Alex Shkurko.pptx
Magento Meetup #12 Anastasiia Bondar
Magento Meetup #12 Vlad Opukhlyi
Google Page Insights and Magento 2 — Sergey Nezbritskiy | Magento Meetup Onli...
Magento NodeJS Microservices — Yegor Shytikov | Magento Meetup Online #11
Magento enhanced media gallery - Alexander Shkurko
7 ошибок одного Black Friday - Влад Опухлый
Magento & Cloud - Korostelov Avexey
Making the Magento 2 Javascript Loading Great Again - Robin van Raan
From Repositories to Commands - Alexander Shkurko
Advanced GIT or How to Change the History
MSI In-Store Pickup Функционал & сложности
Adobe Stock Integration community project
Proof of Concept for Magento 2 Projects: Occamo’s Razor
Что нужно знать девелоперу о SEO на этапе проектирования сайта
Magento-сертификация: инструкция по применению и как это было
Experience in Magento Community Projects
UI components: synergy of backend and frontend
MSI - Reservation Challenges with 3rd-party Systems
Business wants what?!

Deep Dive in Magento DI

  • 1. Deep dive in Magento DI Maksym Grom
  • 2. Немного обо мне Максим Гром Tech Lead in ZFort 3 года с Magento 2 6 лет преподавал в ХАИ MailMaximGrom@gmail.com Веду 2 канала на youtube: Maksym Grom / WebDev. GromMax 47
  • 4. Наследование ∉ киты ООП Композиция - мейнстрим (не только в M2) Private > Protected Interface > Abstract Class VirtualType, Plugin > Rewrite, Preference Что полезного? 49
  • 5. Увидеть новый уровень SOLIDности кода S - один класс одна задача O - все можно расширить L - чистый конструктор I - композиция интерфейсов - мейнстрим D - проси интерфейс, а не реализацию Что полезного? 50
  • 7. DI это когда Что дает DI для M2? ● Все объекты создаются из Inversion of Control (IoC) Container ● IoC Container владеет конфигурацией каждого класса в системе ● Объект просит зависимость через конструктор, а IoC решает что туда передать 52
  • 8. DI недостатки ● Создание дерева зависимостей при создании объекта ● Медленное создание объекта при медленном конструкторе в зависимости ● Накладные расходы из-за рефлексии ● Обслуживание конфигурации (У M2 все есть -> xml) Что дает DI для M2? 53
  • 9. ObjectManager - IoC Что дает DI для M2? 54
  • 10. Декларативная xml схема композиции Что дает DI для M2? 55
  • 11. xsi:type Простые типы: string, boolean, number Опциональный параметр: null Что дает DI для M2? 56
  • 12. xsi:type =”const” Внедрит константу класса как параметр Что дает DI для M2? 57
  • 13. xsi:type =”array” Позволяет строить дерево параметров Что дает DI для M2? 58
  • 15. xsi:type =”object” Создаст shared инстанс класса и внедрит Что дает DI для M2? 60
  • 16. Биндинг интерфейсов к реализациям (SOLID) Что дает DI для M2? 61
  • 17. Перехват публичных методов. Plugins (SOLID) Что дает DI для M2? 62
  • 18. Запуск приложения с разными настройками Initial app/etc/di.xml Global [vendor]/[module]/etc/di.xml Area [vendor]/[module]/etc/[area]/di.xml frontend, adminhtml, webapi_rest, webapi_soap, crontab, graphql Что дает DI для M2? 63
  • 20. Bootstrap App -> app/etc/di.xml Как работает DI? Загрузить initial di.xml (app/etc/di.xml) ObjectManager::configure($di) MagentoFrameworkObjectManagerConfigConfig Подготовка di в php Создать App 65
  • 21. Решить для какой area этот процесс bin/magento http /rest Di global Di global cron:run Di crontab Area crontab cli /?wsdl /admin / Di webapi_rest Area webapi_rest Di frontend Area frontend Di adminhtml Area adminhtml Di webapi_soap Area webapi_soap Cron Job Rest Service Soap Service Action Как работает DI? 66
  • 22. ObjectManager -> create or get (Shared) create($type, $arguments) get($type) Cached? Create type Return object Cache type getPreference true false Как работает DI? 67
  • 23. Create type create($type, $args) $params = resolveParams($type) $params === null return new $type() $args = resolveArguments($params, $args) return create($type, $args) Если аргумент object то создаем через ObjectManager Если shared то через get, иначе через create (рекурсия) Как работает DI? 68
  • 24. Результат в M2. Single Public Method Classes Тип класса Публичные методы Actions dispatch Factory create Observer execute Service execute Repository* get, getById, save, getList, delete Как работает DI? 69
  • 25. Результат в M2 ● Запускаются все конструкторы*, потом методы ● Медленный конструктор - плохо ● Data Transfer Object (DTO) без конструктора Как работает DI? 70
  • 27. Ограничения MagentoFrameworkObjectManagerConfigConfig array_replace переопределяет параметры Ограничения DI Start from class config trim(class, ‘’) isset(args[class]) Обновить аргументы через array_replace true 72
  • 28. Задача, добавить грид в админку ProjectBlogetcadminhtmldi.xml В любом гриде в админке ошибка Невозможно создать [name]_data_source В чем проблема? Ограничения DI 73
  • 29. Задача, добавить грид в админку ProjectBlogetcadminhtmldi.xml CollectionFactory Собирается как global di.xml Ограничения DI 74
  • 30. Ограничения MagentoFrameworkObjectManagerConfigConfig MyClass === MyClass issue #21193 #21796 Start from class config trim(class, ‘’) isset(args[class]) Обновить аргументы через array_replace true Ограничения DI 75
  • 31. Задача, добавить грид в админку ProjectBlogetcdi.xml Не используйте слеш перед именем класса! Ограничения DI 76
  • 34. Регистрируй в DI новый тип Заменяй аргументы конструктора Virtual type 79
  • 35. Внедряй новый тип на место старого Virtual type 80
  • 36. Или получай через ObjectManager Или внедряй как Block Или внедряй как ViewModel Virtual type 81
  • 37. Примечание ● VirtualType может быть создан из VirtualType ● Параметры конструктора type и virtualType склеиваются через array_replace ● Для класса типа Pool нужно обеспечить возможность склейки типов Virtual type 82
  • 38. Pool, склеиваем массив в конструкторе Virtual type 83
  • 39. Задача ● Загрузить список продуктов ● Продукты конкретной категории ● Если категория anchor, то загрузить продукты дочерних категорий Virtual type 84
  • 40. Наши пожелания ● Создать как можно меньше кода ● Не создавать новые API сервисы ● В идеале использовать MagentoCatalogApiProductRepositoryInterface ● Не использовать ProductCollection как зависимость в своем коде Virtual type 85
  • 41. Посмотрим что есть в ProductRepository Virtual type 86
  • 42. Изучим что за ProductCollectionProcessor Фильтры - то что нужно Virtual type 87
  • 43. FilterProcessor Ура! Есть место и пример класса для внедрения Virtual type 88
  • 44. Внедряем свой класс для фильтра Ключ важен! Virtual type 89
  • 45. Осталось реализовать фильтр $collection умеет делать такую фильтрацию Virtual type 90
  • 47. VirtualType. Вывод ● Это экземпляр базового класса ● Идеально для композиции ● Массивы в конструкторе замещаются полностью ● Можно создать через ObjectManager ● VirtualType можно сделать из VirtualType Virtual type 92
  • 49. Plugin регистрируется в di.xml Перехватывает любой публичный метод Класс плагина не нужно наследовать Plugin это shared объект Plugins 94
  • 50. Как DI решает кого плагинить (dev mode) Начало Сканировать методы before[MetodName] around[...], after[...] Есть плагины в цепочке Завершить для этого класса Вычислить цепочку родителей (классы, интерфейсы) Генерировать Interceptor Подготовить конфиг очередности вызовов для методов Этот класс Final? Сортировать плагины Подменить класс на Interceptor true false true false Plugins 95
  • 52. Around может прерывать цепочку вызовов Plugins 97
  • 53. Plugins не работают для Static method - Должен быть создан класс через ObjectManager Private method - Не наследуются в Interceptor Protected method - Нарушение SOLID принципов (use preference) VirtualType - новый объект, а не класс - Плагинится класс Plugins 98
  • 54. Plugins. Вывод ● Используй на классы другого модуля ● Делай stateless plugin - shared object ● Before plugin для подмены входных параметров ● After plugin для подмены результата ● Around plugin > preference ● Используй на Interface > Class Plugins 99
  • 56. Задача подготовить массив моделей из CSV Модель другого модуля с интерфейсом Интерфейс с пометкой @api, модель нет ● Через конструктор можно получить только один объект или shared ● Через new нельзя создавать интерфейсы ● Классы без @api могут быть удалены - проблема обновлений Factory. Набрать массив интерфейсных моделей 101
  • 57. Magento создаст фабрику автоматически по наличию постфикса Factory Factory. Набрать массив интерфейсных моделей 102
  • 58. Factory без хардкода Factory. Набрать массив интерфейсных моделей 103
  • 59. Factory. Вывод ● Нужно создавать объекты? Используй Factory ● Factory - пример класса без хардкода ● Генерация Factory гарантирует однотипность этого подхода Factory 104
  • 60. Proxy
  • 61. Задача сделать CLI, работающую с frontend area И загрузить продукт со SKU “Test” Vendor/Module/etc/di.xml Proxy. CLI, загрузка продукта SKU TEST 106
  • 62. Добавим зависимости Proxy. CLI, загрузка продукта SKU TEST 107
  • 63. Инициализируем area и di в начале метода execute 1. Активирует area для специальных случаев (загрузка сессии) 2. Подключает DI для area Proxy. CLI, загрузка продукта SKU TEST 108
  • 64. Проблема. ProductRepository создан в конструкторе 1. Обращение к БД в конструкторе CLI 2. Создание класса до готовности DI (1-2-3 -> 2-1-3) Proxy. CLI, загрузка продукта SKU TEST 109
  • 65. Подменяем класс на Proxy Proxy - отложенная загрузка класса. При первом запросе к proxy объекту будет создан исходный объект. Назначайте Proxy только через di.xml Proxy. CLI, загрузка продукта SKU TEST 110
  • 66. Integration Test Начало Очистка тестовой DB bin/magento setup:upgrade Запуск тестов на новой БД Создает ConsoleListInterface Создает все объекты команд Для каждой команды строится дерево зависимостей -Запрос к БД ломает наполнение БД -ResourceModel делает запрос к БД -Repository внедряет ResourceModel Proxy 111
  • 67. Repository 1-3 ломает запуск тестов ConsoleListInterface CLI #1 CLI #2 CLI #3 CLI #4 Service #1 Repository #2 Repository #3Service #2 Repository #1 Service #3 Proxy 112
  • 68. Proxy обрывает дерево зависимостей ConsoleListInterface CLI #1 CLI #2 CLI #3 CLI #4 Service #1 Repository #2 Repository #3Service #2 Repository #1 Service #3 Proxy 113
  • 69. S#2 -> R#2 ломает тесты, добавим прокси ConsoleListInterface CLI #1 CLI #2 CLI #3 CLI #4 Service #1 Repository #2 Repository #3Service #2 Repository #1 Service #3 Proxy 114
  • 70. S#1 -> R#1 новая связь, ломает тесты ConsoleListInterface CLI #1 CLI #2 CLI #3 CLI #4 Service #1 Repository #2 Repository #3Service #2 Repository #1 Service #3 Proxy 115
  • 71. S#1 -> R#1 опять PROXY :(. Может есть выход? ConsoleListInterface CLI #1 CLI #2 CLI #3 CLI #4 Service #1 Repository #2 Repository #3Service #2 Repository #1 Service #3 Proxy 116
  • 72. Внедряй на 1 CLI 1 Service + Proxy ConsoleListInterface CLI #1 CLI #2 CLI #3 CLI #4 Service #1 Repository #2 Repository #3Service #2 Repository #1 Service #3 CLI Service #2CLI Service #1 CLI Service #4 CLI Service #3 Proxy 117
  • 73. Proxy. Вывод ● Всегда проксируй зависимости CLI ● Минимизируй количество зависимостей CLI ● Используй Proxy для медленного конструктора Proxy 118
  • 75. Выводы в целом ● Создавай объекты через Factory ● Медленный конструктор - плохо (Proxy) ● Используй композицию вместо наследования ● Используй чужой код через VirtualType ● Инициализируй сервис через конструктор ● Расширяй сервисы через Plugin 120
  • 76. Что почитать - https://devdocs.magento.com/guides/v2.3/extension-dev-guide/build/di-xml-file.html - https://devdocs.magento.com/guides/v2.3/extension-dev-guide/factories.html - https://devdocs.magento.com/guides/v2.3/extension-dev-guide/proxies.html - https://devdocs.magento.com/guides/v2.3/extension-dev-guide/code-generation.html - https://alanstorm.com/magento_2_object_manager_virtual_types/ - https://devdocs.magento.com/guides/v2.3/extension-dev-guide/attributes.html - https://devdocs.magento.com/guides/v2.3/extension-dev-guide/searching-with-repositories.html 121
  • 77. Q&A