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.xml
que agregue el atributo a la interfaz de la entidad - Cree un complemento para agregar el valor del atributo a la
ExtensionAttributes
instancia de las entidades .
Para hacer el segundo punto, ExtensionAttributes
se 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\CartItemExtensionFactory
debe 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\CartItemExtensionInterface
con 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\ExtensionAttributesInterfaceGenerator
y \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
developer
y 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\CartItemExtensionFactory
y no existe, sucede lo siguiente:\Magento\Framework\Code\Generator\Autoloader::load
Factory
(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 faltaFactory
sufijo, 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 ExtensionExtension
y\Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator
será usado para generar esta claseMagento\Quote\Api\Data\CartItemInterface
existe 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\CartItemExtension
implementaMagento\Quote\Api\Data\CartItemExtensionInterface
, lo que no existeExtensionInterface
y\Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator
será 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.xml
porque 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\ExtensionAttributesFactory
es 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