Pregunta

Cuando creo que tengo la cabeza envuelta en el sistema DI de Magento 2, aparece algo y lo desenvuelve.
Veo en el código principal diferentes formas de acceder a un asistente.
Por ejemplo en Magento\Catalog\Controller\Category::_initCategory hay esto:

if (!$this->_objectManager->get('Magento\Catalog\Helper\Category')->canShow($category)) {
    return false;
}

Pero en Magento\Catalog\Block\Category\View el ayudante se inyecta en el constructor

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\Catalog\Model\Layer\Category $catalogLayer,
    \Magento\Framework\Registry $registry,
    \Magento\Catalog\Helper\Category $categoryHelper,
    array $data = array()
) {
    $this->_categoryHelper = $categoryHelper;
    $this->_catalogLayer = $catalogLayer;
    $this->_coreRegistry = $registry;
    parent::__construct($context, $data);
}

Esto me lleva a pensar que se debe acceder a los ayudantes de manera diferente en controladores y bloques (y modelos), pero luego encontré un controlador donde se inyecta un ayudante en el constructor. Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute.

Por favor, despeja la niebla por mí.
¿Cuándo debo usar DI y cuándo debo usar? objectManager?¿y por qué?
He leído esta pregunta: Creación de instancias de ayudantes en Magento 2.Esta es solo una pregunta de seguimiento sobre eso.

¿Fue útil?

Solución

Preferiría DI siempre que sea posible, ya que usar el administrador de objetos ya es una violación de la ley de Demeter.Cuando se utiliza el administrador de objetos, estas dependencias simplemente están ocultas en la lógica del método.

Otros consejos

No sé mucho sobre la implementación de Magento, pero parece que ObjectManager es un Localizador de servicios.

Generalmente, usar un localizador de servicios para acceder a las dependencias de un objeto es bastante malo, consulte Este artículo.

Definir explícitamente sus dependencias a través de un constructor es un enfoque mucho mejor.Ayuda en pruebas unitarias y problemas de tiempo de ejecución con servicios que no están definidos.

Inyectar el Administrador de objetos en una clase es básicamente inyectar un Registro en su clase que tiene acceso a todos los servicios de sus aplicaciones, lo cual obviamente no es correcto.

yo suelo ZF2 bastante y, en general, define pequeñas clases de fábrica para servicios, controladores y cualquier clase que requiera dependencias.Estas clases de fábrica tienen acceso al localizador de servicios, toman todos los servicios de los que depende el objeto y los inyectan a través del constructor.Usar un localizador de servicios en una clase Factory está bien ya que en su mayoría es código desechable, algo así como este Por ejemplo.

Estas fábricas todavía son fáciles de prueba.

En mi opinión, utilice la inyección de constructor siempre que sea posible.Nuevamente, no sé mucho sobre la implementación de Magento y si tiene el concepto de Fábricas, de un vistazo rápido parece que las admite, pero definir explícitamente sus clases y usar un Localizador de servicios para construirlas en las clases de Fábrica es un enfoque mucho más limpio.

Esto es de alguien que tiene una exposición limitada a los patrones mencionados anteriormente, por lo que también me gustaría escuchar los pensamientos/experiencias de otros sobre el tema.

Más lectura

Otra forma de utilizar el asistente (en plantillas) es:

$this->helper('[Vendor]\[Module]\Helper\[Helper Name]')->getMethodName();

Espero que te sea útil si aún no lo sabías.

Aunque es una vieja pregunta, no estoy seguro de si Mario obtuvo su respuesta.Yo creo Mario puedo responderlo mejor.Me gustaría responderla brevemente.¿Por qué Magento 2 sugiere utilizar DI en lugar de ayudante?

  • Hacer posible/fácil el aislamiento en las pruebas unitarias
  • Definir explícitamente las dependencias de una clase.
  • Facilitar un buen diseño (Principio de responsabilidad única (SRP) por ejemplo)
  • El uso de DI en su módulo reduce el riesgo de errores de incompatibilidad cuando Magento cambia la implementación subyacente de esas interfaces.Este es un concepto importante que deben comprender los desarrolladores de extensiones.

¿Por qué es posible que el núcleo M2 no utilice DI en algunos casos?

  • Número decreciente de clases.
  • No crear interfaces innecesarias.
  • No hay riesgo de errores de incompatibilidad

Aunque el módulo de catálogo principal se ha utilizado como ayuda, se ha utilizado DI ampliamente.En mi investigación, descubrí que Magento 2 usaba pocas funciones en los archivos auxiliares de Core Catalog que no son adecuadas para contratos de servicio.

Si debe utilizar explícitamente una clase definida por Magento (como \Magento\Catalog\Model\Product), haga explícita la dependencia implícita dependiendo de la implementación concreta en lugar de la interfaz del contrato de servicio.

Sin duda, el desarrollador de extensiones debería usar DI en lugar de Magento1 como Helper.Cuando se implementa de acuerdo con las pautas de Magento 2, las consecuencias son limitadas.Cuando se incumplen las recomendaciones, surgen problemas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a magento.stackexchange
scroll top