No entiendo por qué, en algunas clases, sus inyecciones de dependencia se declaran dos veces, una en di.xml
y en el constructor de la clase concreta.
Por ejemplo Magento\Backend\Model\Url
, di.xml
tiene definido este conjunto de tipos para DI:
<type name="Magento\Backend\Model\Url">
<arguments>
<argument name="scopeResolver" xsi:type="object">
Magento\Backend\Model\Url\ScopeResolver</argument>
<argument name="authSession" xsi:type="object">
Magento\Backend\Model\Auth\Session\Proxy</argument>
<argument name="formKey" xsi:type="object">
Magento\Framework\Data\Form\FormKey\Proxy</argument>
<argument name="scopeType" xsi:type="const">
Magento\Store\Model\ScopeInterface::SCOPE_STORE </argument>
<argument name="backendHelper" xsi:type="object">
Magento\Backend\Helper\Data\Proxy</argument>
</arguments>
</type>
Pero al mismo tiempo, en su clase concreta, las clases definidas en di.xml requeridas para inyección se vuelven a declarar nuevamente en el constructor:
<?php
public function __construct(
\Magento\Framework\App\Route\ConfigInterface $routeConfig,
\Magento\Framework\App\RequestInterface $request,
\Magento\Framework\Url\SecurityInfoInterface $urlSecurityInfo,
\Magento\Framework\Url\ScopeResolverInterface $scopeResolver,
\Magento\Framework\Session\Generic $session,
\Magento\Framework\Session\SidResolverInterface $sidResolver,
\Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolverFactory,
\Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver,
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
$scopeType,
\Magento\Backend\Helper\Data $backendHelper,
\Magento\Backend\Model\Menu\Config $menuConfig,
\Magento\Framework\App\CacheInterface $cache,
\Magento\Backend\Model\Auth\Session $authSession,
\Magento\Framework\Encryption\EncryptorInterface $encryptor,
\Magento\Store\Model\StoreFactory $storeFactory,
\Magento\Framework\Data\Form\FormKey $formKey,
array $data = []
) {
//...
}
?>
Si miramos su constructor arriba \Magento\Framework\App\Route\ConfigInterface $routeConfig
, por ejemplo, no está definido en di.xml
. Solo se define en el constructor y Magento todavía inyectará routeConfig
en la clase para su uso, ¿no? Lo mismo para \Magento\Framework\Encryption\EncryptorInterface $encryptor
y algunos otros.
Entonces, ¿por qué existe la necesidad de definir las otras inyecciones en ambos di.xml
y en el constructor cuando tener esas declaraciones en el constructor es suficiente para que Magento inyecte esas dependencias en la clase para su uso?
Es importante comprender la diferencia entre la definición de dependencias y la configuración de dependencias.
Las dependencias no están definidas dentro de di.xml. Las dependencias se definen dentro del constructor de la clase respectiva especificando una interfaz, un resumen o una fábrica como el tipo de esa dependencia específica, por ejemplo,
$routeConfig
es una dependencia de tipo\Magento\Framework\App\Route\ConfigInterface
.Por otro lado,
di.xml
es el lugar para configurar las dependencias mediante el uso de<preference/>
nodos y / oxpath:type/arguments/argument
nodos (a veces junto con nodos de configuración más avanzados como<virtualType/>
o<proxy/>
). Configurar una dependencia simplemente significa mapear el argumento constructor de un objeto a una implementación / objeto / concreto .Desea que las dependencias sean configurables a través de di.xml para poder intercambiarlas y usar una implementación diferente para una determinada interfaz o argumento bajo ciertas condiciones (siga leyendo el ejemplo para comprender qué se supone que significan ciertas condiciones).
Por ejemplo, al desarrollar su extensión, primero debe crear una nueva clase (llamamos a esta nueva clase una implementación ). Su nueva clase implementa la
\Magento\Framework\App\Route\ConfigInterface
interfaz y tiene dentro de su cuerpo una funcionalidad concreta que hace honor al contrato de la interfaz. Ahora comienza la parte de configuración : para decirle a Magento que use su implementación recién definida, debe configurar esta implementación como una dependencia para el objetoMagento\Backend\Model\Url
. Realiza esta configuración dentro de losdi.xml
archivos o su módulo. En este caso, debe usar el<preference/>
nodo para asignar la interfaz a su nueva implementación. Otras veces usaría elxpath:type/arguments/argument
di.xml
nodo más granular paramapear solo argumentos específicos (también conocidos como dependencias, también conocidos como interfaces) de implementaciones concretas a específicas . Ahora, su aplicación sólo estará activa como una dependencia para el objeto\Magento\Backend\Model\Url
en ciertas condiciones , por ejemplo, en el flujo de la ejecución de código de la solicitud de aplicación actual un objeto del tipoMagento\Backend\Model\Url
que se está creando y que necesita una aplicación para el definido constructor de la dependencia llamada$routeConfig
que es de tipo\Magento\Framework\App\Route\ConfigInterface
.Es más o menos como decir:
"¡Hola, Sr. ObjectManager! Siempre que
Magento\Backend\Model\Url
se solicite una instancia de tipo de objeto, primero eche un vistazo a su definición de constructor de clase y analice las dependencias definidas en ella. Quiero que luego busque dentro dedi.xml
la configuración HTTP final combinada de la solicitud HTTP actual. para cada dependencia configurada que se define en el constructor de clase Magento \ Backend \ Model \ Url . Usted me da esa implementación de dependencia configurada ".fuente