Як Magento2 генерує специфічний ExtensionFactory та ExtensionAttributeInterface?


28

Я хотів би обернути голову, використовуючи атрибути розширення, наприклад, для цитат.
Немає проблеми додавати спеціальний атрибут до такої сутності, використовуючи клас налаштування, як у Magento 1, це питання не стосується цього питання.
На даний момент магія переповнює мене, коли я хочу розкрити такий атрибут, який був доданий розширенням через API сутності як атрибут розширення.

ОНОВЛЕННЯ : Я знаю, як створюються штатні заводи. Це питання стосується спеціальних заводів, які створюють створені реалізації для інтерфейсів створених атрибутів розширення.

Ось кроки, які я вживаю, щоб змусити його працювати. Я додаю це, тому тому, хто намагається відповісти, не потрібно вдаватися до цих деталей.
Моє запитання - ЯК чи ЧОМУ це працює?

Етапи розкриття атрибуту розширення за допомогою API сутності:

  1. Створіть, etc/extension_attributes.xmlщо додає атрибут до інтерфейсу сутності
  2. Створіть плагін, щоб додати значення атрибута до ExtensionAttributesекземпляра сутностей .

Для того, щоб зробити другий пункт, ExtensionAttributesпотрібен екземпляр сутності . З цієї причини плагін залежить від фабрики, яку менеджер об'єктів постачає через DI.

Для котирування товару Magento\Quote\Api\Data\CartItemExtensionFactoryслід використовувати приклад .
Я думаю, що тип цієї фабрики якось повинен стати пусковим механізмом для магії покоління.

Потім Magento генерує відповідний інтерфейс \Magento\Quote\Api\Data\CartItemExtensionInterfaceіз сеттерами та getters для всіх атрибутів розширення.
Однак, схоже, це не генерує конкретної реалізації цього інтерфейсу. В оренді PHPStorm його не бачить.

Як Magento збирає інформацію, необхідну для створення класу? Як можна викликати створені методи інтерфейсу на конкретному екземплярі? Це клас, який просто генерується лише в пам'яті?

Я щасливий, що це працює, але це насправді не задовольняє. Можливість Magentos використовувати атрибути, створені автоматично розширеннями, є одним з ключових факторів його успіху. Як розробник модулів, я вважаю, що мені потрібно глибоке розуміння всього процесу.
Якщо я маю час, я б просто розібратися в цьому сам, але я вважаю за краще, якби я міг отримати пояснення.

ОНОВЛЕННЯ 2 : Витратили трохи часу для читання \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGeneratorта \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator. Тепер я, принаймні, маю грубе уявлення про те, що відбувається. Якщо мене ніхто не переможе, я напишу опис повного процесу в один момент, оскільки, думаю, це буде корисним посиланням.


2
зробив The Vinai .. задав питання .. Омг
Аміт Бера

Відповіді:


26

Перш за все автогенерація відбувається на основі суфіксу імені класу, наприклад Factory, ExtensionInterface(див. \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator::EXTENSION_INTERFACE_SUFFIX) Або Extension(див. \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator::EXTENSION_SUFFIX).

Правильний генератор вибирається на основі суфікса \Magento\Framework\Code\Generator::generateClass.

Припустимо, що режим Magento є, developerі відсутні класи можуть бути згенеровані на льоту (подібний процес відбудеться при використанні компілятора). Коли менеджер об'єктів намагається створити примірник, скажімо, Magento\Quote\Api\Data\CartItemExtensionFactoryі він не існує, відбувається таке:

  1. Автозавантажувач не може інстанціювати клас та ініціює генерування коду тут \Magento\Framework\Code\Generator\Autoloader::load
  2. Потім суфікс класу визначається як Factory(список усіх оголошених суфіксів можна знайти тут \Magento\Framework\ObjectManager\DefinitionFactory::getCodeGenerator) і відповідний заводський клас генератора ( Magento\Framework\ObjectManager\Code\Generator\Factory) використовується для створення відсутнього заводу
  3. Усі автогенеровані класи завжди базуються на інших класах, у випадку фабрики, назва класу джерела обчислюється лише видаленням Factoryсуфіксу, воно буде Magento\Quote\Api\Data\CartItemExtension. Цей клас не існує, і автогенерація знову викликається автозавантажувачем, але цього разу для класу Extension
  4. Тепер суфікс є Extensionі \Magento\Framework\Api\Code\Generator\ExtensionAttributesGeneratorбуде використовуватися для генерації цього класу
  5. Клас джерела для генерації класу Extension обчислюється як Magento\Quote\Api\Data\CartItemInterface, він існує, і клас Extension успішно генерується. Однак, при спробі включити файл класу Extension, автогенерація знову запускається через Magento\Quote\Api\Data\CartItemExtensionреалізацію Magento\Quote\Api\Data\CartItemExtensionInterface, якої не існує
  6. Суфікс є ExtensionInterfaceі \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGeneratorбуде використовуватися для покоління
  7. Класи ExtensionInterface та Extension створюються на основі інформації extension_attributes.xml, доступної через \Magento\Framework\Api\ExtensionAttribute\Config, потім виробляється Factory

Одне важливе зауваження полягає в тому, що немає переваги для ExtensionInterface, di.xmlоскільки і розширення, і ExtensionInterface автогенеруються. Це не є проблемою, оскільки очікується, що ExtentionInterface не буде вводитися безпосередньо через конструкцію.


@Vinai ласкаво просимо. Баунті був приємним сюрпризом, дякую. Оновлення: просто FYI, якщо щедрість була розпочата після прийняття відповіді, вона не присуджується автоматично.
Олексій Паляруш

0

Для мене сьогодні ввечері поверх відповіді від @Alex я бачу рядки

$modelReflection = new \ReflectionClass($extensibleClassName);
        if ($modelReflection->isInterface()
            && $modelReflection->isSubclassOf(self::EXTENSIBLE_INTERFACE_NAME)
            && $modelReflection->hasMethod('getExtensionAttributes')
        ) {
            $this->classInterfaceMap[$extensibleClassName] = $extensibleClassName;
            return $this->classInterfaceMap[$extensibleClassName];
        }

у класі \Magento\Framework\Api\ExtensionAttributesFactory

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

ці рядки говорять:

  • є класом нашого extension_attributes інтерфейсу

  • чи поширюється \ Magento \ Framework \ Api \ ExtensibleDataInterface

  • має цей інтерфейс функцію, яку називають getExtensionAttributes

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