Certificación Magento 2: inyección de dependencia [enfoque y arquitectura]

¡Hola a los lectores del blog de Amasty!

Continuamos con nuestras publicaciones en preparación para el examen de certificación Magento 2. Esta vez le pedimos a Stanislav, uno de los desarrolladores certificados de Magento 1 de nuestro equipo y un ingeniero certificado de Zend, que hablara sobre el enfoque y la arquitectura de inyección de dependencia de Magento. Siga leyendo para descubrir cómo usar la inyección de dependencia de primera mano.

Resumen del artículo [ ocultar ]

  • ¿Qué es la inyección de dependencia de Magento 2?
    • ¿Cómo se realizan los objetos en Magento 2?
      • ¿Cómo obtener un objeto de clase en PHP puro?
    • ¿Cómo obtener un objeto de clase en Magento 2 usando ObjectManager?
    • ¿Por qué es importante tener un proceso centralizado que cree instancias de objetos?
  • ¿Cómo usar los archivos de configuración DI para personalizar Magento 2?
    • ¿Cómo se puede anular una clase nativa?
    • ¿Cómo personalizar Magento 2 usando complementos?
    • ¿Cómo puedes inyectar tu clase en otro objeto?
    • Otras técnicas disponibles en di.xml: VirtualType

¿Qué es la inyección de dependencia de Magento 2?

La inyección de dependencia es un patrón de diseño que permite declarar dependencias de objetos en Magento 2. La realización permite no solo hacer su código más estructural e independiente, sino también hacer que el proceso de codificación sea más conveniente.

¿Cómo se realizan los objetos en Magento 2?

Como sabes, en Magento 1 los objetos se manejan con el uso de la clase Mage. En Magento 2 usamos el Administrador de Objetos y la Inyección de Dependencia que reemplazó la funcionalidad provista por el Mage. Esto ha permitido el acoplamiento flojo del código.

Lea la documentación oficial sobre DI aquí .

¿Cómo obtener un objeto de clase en PHP puro?

En Magento 2, podemos aplicar $object = new SomeClass(); método para obtener un objeto de clase en PHP puro. Sin embargo, nos veremos privados de los beneficios del uso de Magento 2 ObjectManager.

Para obtener más información sobre ObjectManager, lea aquí .

¿Cómo obtener un objeto de clase en Magento 2 usando ObjectManager?

Difícilmente puede ver los beneficios de $objectManager->create(‘SomeClass’); variante. Pero veamos esto con más detalle.

La primera (1) ventaja del método es que en lugar de escribir su Singleton para una clase, puede usar $objectManager->get(‘SomeClass’); para aplicar Singleton para cualquier clase.

Si desea saber cómo funciona, consulte aquí: MagentoFrameworkObjectManagerObjectManager.

La segunda (2) ventaja radica en la posibilidad de utilizar la Inyección Automática de Dependencias . Entonces, ¿qué te da eso? Esto le permite hacer inyecciones de código en el código existente.

En este caso, podemos cambiar el imageUploader por cualquier otra variante. Además, no tendremos que hacer ningún cambio en la clase original. Cuando se utiliza ObjectManager para la creación de clases, las dependencias se sustituyen automáticamente desde el constructor de clases.

Junto con esto, existe la tercera (3) ventaja. Es posible inyectar las dependencias de la clase en el constructor de clases a través del archivo di.xml , lo que puede ser muy conveniente. Por ejemplo: digamos que tenemos la siguiente clase con el constructor MagentoFrameworkAppRouterList:

public function __construct(MagentoFrameworkObjectManagerInterface $objectManager, array $routerList)

Podemos agregar el siguiente código en el archivo di.xml del módulo:

y, como resultado, el parámetro definido en el archivo di.xml se inyectará en el constructor routerList en MagentoFrameworkAppRouterList.

Al transferir clases a un constructor, se aplica el mismo  código $objectManager->create(SomeImageUploader) . Y si pasa SomeImageUploaderFactory en lugar de SomeImageUploader al constructor, se creará una fábrica automáticamente. Por ejemplo: digamos que hay una clase SomeImageUploader y necesitamos obtener una fábrica SomeImageUploader en otra clase. Para esto, debe agregar SomeImageUploaderFactory al constructor y luego usar $this->imageUploaderFactory>create(); para obtener el objeto de clase:

Tenga en cuenta que en la clase SomeImageUploader hay una variable imageUploaderFactory a la que le hemos asignado el valor SomeImageUploaderFactory .

Obtenga más información sobre las fábricas aquí . Debido a la generación automática, el proxy también está disponible. Encuentre más información al respecto aquí .

Por lo tanto, no necesitamos escribir una fábrica manualmente, debido a la generación automática de código. Puede obtener más información sobre la generación de código desde aquí .

¿Por qué es importante tener un proceso centralizado que cree instancias de objetos?

Es gracias a la creación centralizada de objetos que puede utilizar las ventajas descritas anteriormente. Además, le brinda la posibilidad de evitar la herencia, lo que significa que las aplicaciones se vuelven más flexibles. En esto, no necesita pensar en las clases secundarias al cambiar la principal.

¿Cómo usar los archivos de configuración DI para personalizar Magento 2?

Para personalizar Magento 2, debe trabajar en el archivo de configuración DI <moduleDir>/etc/di.xml .

¿Cómo se puede anular una clase nativa?

El método se parece a las reescrituras en Magento 1 y también permite la reescritura de clases. Sin embargo, si tiene la posibilidad de usar complementos, no aplique el método de reescritura. Puede generar conflictos cuando hay otras extensiones. P.ej: 

¿Cómo personalizar Magento 2 usando complementos?

Los complementos se pueden aplicar al cambio de comportamiento flexible de las funciones públicas. P.ej:

Puedes leer más sobre su uso aquí .

¿Cómo puedes inyectar tu clase en otro objeto?

Puede encontrar ejemplos de inyecciones de clase en otro objeto en el código de Magento 2. Por ejemplo: digamos, MagentoSalesModelResourceModelProviderUpdatedIdListProvider es nuestra propia clase que queremos inyectar y el proveedor/magento/module-sales/Model/ResourceModel/Provider/NotSyncedDataProvider.php es el objeto de clase en el que vamos a inyectar nuestra clase:

Otras técnicas disponibles en di.xml: VirtualType

Los tipos virtuales son convenientes para DI solo en caso de que necesitemos indicar nuestras clases en las dependencias. Por lo tanto, no necesitará crear una clase separada.

Puede encontrar muchos ejemplos en Magento 2 simplemente usando la consulta de búsqueda virtualType en el archivo di.xmlPor ejemplo: en el archivo magento2/vendor/magento/module-sales/etc/di.xml:

¡Es todo por hoy! Esperamos que la publicación lo ayude a recibir un resumen de DI en Magento 2. Consulte los DevDocs oficiales de Magento para obtener más información.

Escríbanos si todavía tiene preguntas sobre el tema.

¡Manténganse al tanto!