Categories: Мадженто 2

Ін’єкції залежностей в Magento 2 – основи їх використання

Однією з найбільших змін у Magento 2 (у порівнянні із версіями 1.х) є використання патерну ін’єкцій залежностей. Через цей шаблон проектування в базі коду багато чого було змінено та було введено багато нових елементів. Сьогоднішня стаття покликана пояснити початківцям саму основу цього шаблону проектування та використання ін’єкцій залежностей в Magento 2.

 

Насамперед розглянемо основну ідею використання цього патерну (шаблону проектування). Виконуючи ін’єкцію залежностей, вам потрібно запитувати залежні ресурси під час створення об’єкта, замість створення ресурсів, коли вони потрібні. Це дозволить досягти ізоляції класу і незалежної розробки, так як і простого тестування через легкість згладжування необхідних об’єктів. Перш ніж продовжувати, дозвольте продемонструвати невеличкий приклад:

 

class A
{
 ...
 public function read()
 {
  $dbh = new DatabaseConnection(); // уникайте такого
  $dbh->query('SELECT ...');
  ...
 }
 ...
}

 

Попередній приклад демонструє простий клас А з методом read(). У цьому методі нам потрібен об’єкт для з’єднання з базою даних, який створюється в першому рядку методу. Це те, до чого більшість з нас звикла, і це дещо схоже на те, що використовується в Magento 1.x (фабричний патерн). Наступний приклад реалізує ту ж саму логіку, але за патерном ін’єкції залежностей:

 

class A
{
 protected $_dbh;
 ...
 public function __construct(DatabaseConnection $connection)
 {
  $this->_dbh = $connection;
 }
 ...
 public function read()
 {
  $this->_dbh->query('SELECT ...');
 ...
 }
 ...
}

 

У цьому прикладі об’єкт з’єднання з базою даних був переданий класу А через конструктор, а не створювався в межах методу read(). Незважаючи на те, що це не єдиний спосіб передачі залежностей об’єкту, така реалізація використовується в Magento 2. Отже, що саме це нам дає?

Клас А може бути розроблений незалежно від класу DatabaseConnection, оскільки ми можемо завжди підробляти зв’язок для цілей розробки. Він не залежить від реалізації DatabaseConnection і в такий спосіб набагато простіше перевірити наш код.

Одним із недоліків є те, що другий приклад коду трохи більший за перший. І це правда, для прикладу Magento\Catalog\Model\Product має конструктор, який займає більше 50 рядків коду. Крім того, якщо ви спробуєте налагодити цей код, ви побачите, що це дуже важке завдання. На щастя, тут на допомогу приходить тестування.

Для ініціалізації таких великих об’єктів ін’єкції залежностей мають контейнер для ін’єкцій залежностей, а в Magento 2 він називається ObjectManager. Цей контейнер відповідає за розбір та створення залежностей після створення об’єктів. Давайте розглянемо, як це працює на простому прикладі:

 

class A
{
 public function __construct(B $b)
 {
  $this->_b = $b;
 }
}

 

При створенні об’єкта з класу А відбувається таке:

  • викликається ObjectManager->create('A')
  • розглядається Конструктор А
  • створюється Клас B і використовується для створення A

 

У цих кількох кроках ObjectManager створив об’єкт із класу. Але на даний момент не будемо вважати це таким простим і уявимо собі, що в нас є декілька реалізацій класу B. Це ставить питання, яку реалізацію буде використано? І відповідь на це питання можна знайти в одному з файлів di.xml, які розташовані в наступних місцях:

  • {папка_модуля}/etc/(область_коду)/di.xml
  • {папка_модуля}/etc/di.xml
  • app/etc/di/*.xml

 

У цих файлах ви можете знайти/вказати такі налаштування:

  • Визначення класів: тип і кількість залежностей. На щастя, Magento 2 використовує підпис конструктора для автоматичної компіляції
  • Конфігурація екземпляра. Визначення способу інстанціювання об’єктів. Це передбачає встановлення types та virtualTypes
  • Розробка карти абстракції-впровадження: це дозволяє вибрати потрібну імплементацію інтерфейсу. Це щось подібне до перевизначення (rewrite) в Magento 1.x.

 

Ще одна річ, яку потрібно пояснити, — тип об’єктів для ін’єкції. У Magento 2 вони розділені на дві групи: ін’єкційні та неін’єкційні. Спочатку розглянемо неін’єкційні об’єкти. Після цього ви самі впізнаєте ін’єкційні об’єкти.

Наприклад, давайте розглянемо сторінку товару, на якій ви хочете відобразити поточний товар та деякі пов’язані товари. Якщо ви передаєте модель товару до свого контролера, спершу вам потрібно буде викликати завантаження цього товару, щоб отримати поточний товар. Але як тільки цей об’єкт буде використовуватись, де ви отримаєте інформацію про інші товари? Тож тут ми усвідомлюємо, що модель товару – це один з об’єктів, що не є ін’єкційними. Насправді, всі об’єкти, які мають певний тип ідентичності, можуть бути неін’єкційними: товари, замовлення, елементи кошика, користувачі, …

Щоб використовувати в коді неін’єкційні об’єкти, ви повинні подати запит на їх фабрику (factory). Наприклад, якщо ви намагаєтеся завантажити декілька товарів, ваш код буде залежати від фабрики товару, і через цей об’єкт ви будете викликати метод create() з ідентифікацією товарів, які ви намагаєтеся завантажити. Проксі (proxies) призначені, головним чином, для відкладеного завантаження необов’язкових або «важких» залежностей.

 

 

 

От ми і розглянули коротко самі основи шаблону проектування з використанням ін’єкцій залежностей. Сподіваємось, що ця інформація дозволить вам мати певний багаж знань перед більш поглибленим вивченням цієї теми. Для цього ви можете ознайомитись із специфікацією на офіційному сайті Magento.

 

This post was last modified on 13/08/2018 17:30

Share
Підтримай проект
Пригости мене кавою

Buy Me A Coffee ☕😊💕

 

 

Останні пости

Генрі Форд

Людина має два мотиви поведінки — один справжній та інший, що гарно звучить Генрі Форд…

16/07/2024

Фрідріх Ніцше

Не треба додумувати надто багато. Так ви створюєте проблеми, яких не існувало Фрідріх Ніцше  

11/07/2024

Такий різний інвертор! Вибираємо між кондиціонерами Inverter, Inverter DC та Full DC

Літо в розпалі, а значить якраз час задуматися про покупку кондиціонера. Але як не загубитися…

06/07/2024

Омар Хайям

Справжній друг — це людина, яка в очі викаже тобі все, що про тебе думає,…

30/06/2024

Корисні поради щодо вибору розсувних дверей

Варто знати, що функціональність і дизайн працюють рука об руку, коли ви використовуєте розсувні двері.…

29/06/2024

Геракліт

Єдине, що постійне, — це зміни. Немає нічого постійного окрім змін. Усе плине, усе змінюється.…

23/06/2024