Введення залежностей у модель Magento 2 CRUD / абстрактна модель


12

Чи можна ввести залежність до моделі Magento 2 CRUD?

Тобто - Magento 2 має базовий абстрактний клас моделі: Magento\Framework\Model\AbstractModel. Якщо ви хочете створити простий об’єкт "Створити, прочитати, оновити", "Видалити модель", ви розширите цей клас власним класом.

class Foo extends Magento\Framework\Model\AbstractModel
{
}

Чи можливо ввести __constructметод залежно від методу вашої моделі ? Коли я намагаюся, я отримую таку помилку.

Фатальна помилка: Неможливо створити абстрактний клас Magento \ Framework \ Модель \ ResourceModel \ AbstractResource

Злочинець , здається, AbstractModel«S __constructметод.

public function __construct(
    \Magento\Framework\Model\Context $context,
    \Magento\Framework\Registry $registry,
    \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
    \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
    array $data = []
) {

У цьому конструкторі є два підказки типу ( Magento\Framework\Model\ResourceModel\AbstractResource, Magento\Framework\Data\Collection\AbstractDb), які не є інтерфейсами Magento-менеджера об'єктів. Вони абстрактні класи. Коли я розширюю цей клас і намагаюся додати свою ін'єкційну залежність

class Foo extends Magento\Framework\Model\AbstractModel
{
    public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
        \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
        array $data = [],
        \Package\Module\Model\Mine $mine,

    ) {
        //...
        parent::__construct($context, $registry, $resource, $resourceCollection, $data);

    }
}

Magento віддає під заставу, коли менеджер об'єктів намагається створити абстрактні класи.

Я можу "виправити" це, перемістивши свою об'єктну залежність перед абстрактними класами

    public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,

        \Package\Module\Model\Mine $mine,

        \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
        \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
        array $data = [],
    ) {  

Однак це змінило порядок аргументів. У класі, яким керували повністю об'єкти, це не було б проблемою. Однак, факт існування цих абстрактних натяків типу класу означає, що існують частини системи Magento, які вручну (тобто не через диспетчер об'єктів або DI) інстанціюють об'єкти CRUD та передаватимуть об'єкти, які відповідають натякам на тип у цьому конкретному порядку .

Це безпечно? Чи є ці абстрактні класи в конструкторі абстрактної моделі лише застарілим кодом і не використовуються? Або частини системи все одно використовуватимуть це, тобто неможливо ввести залежності в модель CRUD?

Відповіді:


9

Перш за все конструктор - це приватні api класу. Функція конструктора має особливе значення і не потребує того, щоб вони мали такий самий список / порядок аргументів, як у батьківському класі.

Чи можна ввести залежність до моделі Magento 2 CRUD?

Так, звісно.

Це безпечно?

Так, але Magento Object Manager припускає, що всі необов'язкові параметри розміщуються в кінці списку, а необхідні параметри після необов'язкового не будуть вирішені.

Аргументи $ resource, $ resourceCollection застаріли, але все ще широко використовуються в класах Model. Більшість моделей використовують такий код, як ініціалізація класу ресурсів та колекції.

protected function _construct() { 
    $this->_init('Magento\AdminNotification\Model\Resource Model\Inbox'); 
}

Ось чому цей параметр необов’язковий. Але, наприклад, в тестовому блоці ми передаємо ресурс або макет збору в конструктор, щоб дозволити реалізацію заміни.


@Kanday Чи інженерно-архітектурний відділ Magento коли-небудь оприлюднив заяву про те, що замовлення конструктора для основних класів не має значення? Або це лише надія більшості людей, які працюють над цим?
Алан Шторм

Я не буду називати це "неактуальним". Просто OM передасть необхідні аргументи вашому конструктору, і це не залежить від порядку в батьківському класі. Більше того, IN використовує назви параметрів, тому тепер краще не змінювати їх (це відрізняється від мови php, де ви можете змінювати назви параметрів, як хочете)
KAndy,

Я не впевнений, що розумію, що ти кажеш. Ви хочете сказати, що в якийсь момент основний системний код Magento може знову почати трактувати аргумент / параметр як вагомий?
Алан Шторм

Я вважаю, що ні
Кенді

знову дякую! FWIW, а для Googlers це здається, що це слід зробити безпечним. З того, що я можу сказати, немає системного коду Magento, який автоматично сліпо створює модель, припускаючи порядок параметрів конструктора.
Алан Шторм

6

Це здається безпечним. Принаймні, Магенто робить це в ряді місць. Дивіться методи __construct у наступному (неексклюзивному) списку класів для прикладів

  • \ Magento \ Тема \ Модель \ Тема \ Файл
  • \ Magento \ Тема \ Модель \ Дизайн
  • \ Magento \ Продажі \ Модель \ Замовлення \ Кредитна пам'ятка

На жаль, я не можу відповісти на іншу частину вашого запитання.


4
  1. Як ви використовуєте свою модель?
  2. У вашому випадку $mineце потрібно параметр, в той час $resource, $resourceCollectionі $dataє по бажанню . Необов’язкові параметри завжди повинні бути останніми, інакше працювати з ними просто неможливо, як з необов'язковими. Тому мені здається, що вам слід вказати $mineперед будь-якими необов'язковими параметрами.

За винятком цих абстрактних параметрів - це не параметри, які вводяться в залежність, і якщо основний код системи Magento очікує, що вони будуть там, переходячи $mineна передню частину черги, створюватимуть помилки. Якщо основний системний код Magento не використовує їх, то навіщо вони там? Це питання, яке я намагаюся дістати донизу. Тільки тому, що я можу використовувати свою модель із переміщеним параметром, це не робить її безпечною.
Алан Шторм

Деякі моделі все ще можуть використовувати ці необов'язкові параметри для передачі спеціальної моделі ресурсів. Наприклад, github.com/magento/magento2/blob/develop/app/code/Magento/…
BuskaMuza

Magento використовує відображення для визначення того, чи є параметр необов’язковим чи ні. І PHP розглядає всі параметри, що стоять перед необхідним параметром, як необхідні . Отже, якщо ви переходите $mineдо необов'язкових параметрів, вони стають дійсно необов’язковими, і Magento просто передає значення за замовчуванням ( null, array()). Якщо ви ставите потрібний параметр після необов'язкових, PHP вважає необов'язкові параметри необхідними, і Magento намагався їх інстанціювати (але для них немає переваг).
БуськаМуза

Хоча я згоден, що це виглядає заплутано, і, можливо, ми могли б просто встановити перевагу абстрактним класам, а не обробляти їх усередині модельного класу. Тож справжній предмет завжди вводиться.
BuskaMuza
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.