Me gustaría entender cómo usar los atributos de extensión, por ejemplo, para los elementos de cotización.
No es ningún problema agregar un atributo personalizado a dicha entidad utilizando una clase de configuración como en Magento 1, de esto no se trata esta pregunta.
En este momento, la magia me abruma cuando quiero exponer un atributo que fue agregado por una extensión a través de la API de entidades como un atributo de extensión.
ACTUALIZACIÓN : Sé cómo se generan las fábricas regulares. Esta pregunta trata sobre las fábricas especiales que crean instancias de las implementaciones generadas para las interfaces de atributos de extensión generadas.
Estos son los pasos que tomo para que funcione. Estoy agregando estos para que quien intente responder no necesite entrar en esos detalles.
Mi pregunta es CÓMO o POR QUÉ funciona.
Pasos para exponer un atributo de extensión a través de una API de entidad:
- Cree un
etc/extension_attributes.xmlque agregue el atributo a la interfaz de la entidad - Cree un complemento para agregar el valor del atributo a la
ExtensionAttributesinstancia de las entidades .
Para hacer el segundo punto, ExtensionAttributesse necesita la instancia de las entidades . Por esta razón, el complemento depende de una fábrica, que el administrador de objetos suministra a través de DI.
Para el ejemplo del artículo de presupuesto Magento\Quote\Api\Data\CartItemExtensionFactorydebe usarse.
Supongo que el tipo de esta fábrica de alguna manera debe ser el detonante de la magia de la generación.
Luego, Magento genera la interfaz correspondiente \Magento\Quote\Api\Data\CartItemExtensionInterfacecon los establecedores y captadores para todos los atributos de extensión.
Sin embargo, no parece generar la implementación concreta para esa interfaz. Al menos, PHPStorm no lo está viendo.
¿Cómo recopila Magento la información que necesita para generar la clase? ¿Cómo se pueden invocar los métodos de interfaz generados en una instancia concreta? ¿Es una clase que solo se genera en la memoria?
Estoy feliz de que funcione, pero eso no es realmente satisfactorio. La capacidad de Magentos para usar atributos creados automáticamente por extensiones es un factor clave para su éxito. Como desarrollador de módulos, creo que necesito una comprensión profunda de todo el proceso.
Si tuviera tiempo, simplemente investigaría esto yo mismo, pero preferiría si pudiera obtener una explicación.
ACTUALIZACIÓN 2 : Tomó un poco de tiempo para leer \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGeneratory \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator. Ahora al menos tengo una idea aproximada de lo que está sucediendo. Si nadie me gana, escribiré una descripción del proceso completo en un punto, ya que creo que sería una referencia útil.

Respuestas:
En primer lugar, la autogeneración se produce en función del sufijo de nombre de clase, por ejemplo
Factory,ExtensionInterface(ver\Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator::EXTENSION_INTERFACE_SUFFIX) oExtension(ver\Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator::EXTENSION_SUFFIX).El generador adecuado se selecciona en función del sufijo aquí
\Magento\Framework\Code\Generator::generateClass.Supongamos que el modo Magento es
developery que las clases faltantes se pueden generar sobre la marcha (un proceso similar ocurrirá cuando se use el compilador). Cuando el administrador de objetos intenta crear una instancia, digamosMagento\Quote\Api\Data\CartItemExtensionFactoryy no existe, sucede lo siguiente:\Magento\Framework\Code\Generator\Autoloader::loadFactory(la lista de todos los sufijos declarados se puede encontrar aquí\Magento\Framework\ObjectManager\DefinitionFactory::getCodeGenerator) y la clase de generador Factory correspondiente (Magento\Framework\ObjectManager\Code\Generator\Factory) se usa para generar la fábrica que faltaFactorysufijo, lo seráMagento\Quote\Api\Data\CartItemExtension. Esta clase no existe y el autocargador invoca una vez más la autogeneración, pero esta vez para la clase ExtensionExtensiony\Magento\Framework\Api\Code\Generator\ExtensionAttributesGeneratorserá usado para generar esta claseMagento\Quote\Api\Data\CartItemInterfaceexiste y la clase de extensión se genera correctamente. Sin embargo, en el intento de incluir el archivo de clase de extensión, la autogeneración se activa una vez más porque seMagento\Quote\Api\Data\CartItemExtensionimplementaMagento\Quote\Api\Data\CartItemExtensionInterface, lo que no existeExtensionInterfacey\Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGeneratorserá usado para la generaciónextension_attributes.xml, accesible a través de\Magento\Framework\Api\ExtensionAttribute\Config, luego se genera FactoryUna nota importante es que no hay preferencia por ExtensionInterface
di.xmlporque tanto Extension como ExtensionInterface se generan automáticamente. Esto no es un problema porque no se espera que ExtentionInterface se inyecte a través de la construcción directamente.fuente
Para mí, esta noche, además de la respuesta de @Alex, puedo ver las líneas
en la clase
\Magento\Framework\Api\ExtensionAttributesFactoryes donde es posible que queramos comenzar a depurar si no se genera la interfaz de extensión. Casi todos los atributos de extensión se trata de estructurar nuestra clase como Magento 2 esperará.
Estas líneas dicen:
es la clase en nuestra extension_attributes una interfaz
¿se extiende \ Magento \ Framework \ Api \ ExtensibleDataInterface
tiene esta interfaz una función llamada getExtensionAttributes
fuente