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.

 

Share
Published by
SebWeo

Recent Posts

Різниця між Зображенням обкладинки та Обраним зображенням у WordPress

Візуальна привабливість є ключовою особливістю будь-якого сайту на ВордПрес. Відвідувачі частіше будуть відкривати посилання, які…

19 години ago

15 класичних запитань на співбесіді, до яких варто бути готовим програмісту

Будь-які співбесіди завжди хвилюють, і навіть можуть викликати певного ступеню нервозність. Однак, якщо ви будете…

3 дні ago

Артур Шопенгауер

Змінити я цього не можу, залишається отримувати з цього користь Артур Шопенгауер  

4 дні ago

Ернест Хемінгуей

Якщо вас щось ранить, значить, вам не все одно Ернест Хемінгуей  

1 тиждень ago

Як створити власну URL-адресу для входу в WordPress

За замовчуванням після кожної інсталяції WordPress є три основні URL-адреси для входу в адмінку: {домен}/wp-admin.php,…

2 тижні ago

Як відстежувати продуктивність фрилансера без складного софту

Продуктивність - це валюта фрилансера. Коли ти працюєш сам на себе, ніхто не запитає: «Скільки…

2 тижні ago