Je ne comprends pas pourquoi, dans certaines classes, leurs injections de dépendances sont déclarées deux fois - une fois dans le di.xml
constructeur de la classe concrète.
Par exemple dans Magento\Backend\Model\Url
, son di.xml
a cet ensemble de types pour DI défini:
<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>
Mais en même temps, dans sa classe concrète, les classes définies dans di.xml requises pour l'injection sont à nouveau déclarées dans le constructeur:
<?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 nous regardons son constructeur ci-dessus \Magento\Framework\App\Route\ConfigInterface $routeConfig
, par exemple, il n'est pas défini dans di.xml
. Il n'est défini que dans le constructeur et Magento injectera toujours le routeConfig
dans la classe pour utilisation, n'est-ce pas? Pareil pour \Magento\Framework\Encryption\EncryptorInterface $encryptor
et quelques autres.
Alors, pourquoi est-il nécessaire de définir les autres injections à la fois di.xml
et dans le constructeur quand avoir ces déclarations dans le constructeur est suffisant pour que Magento injecte ces dépendances dans la classe pour utilisation?
Il est important de comprendre la différence entre la définition des dépendances et la configuration des dépendances.
Les dépendances ne sont pas définies dans di.xml. Les dépendances sont définies à l'intérieur du constructeur de la classe respective en spécifiant une interface, un résumé ou une fabrique comme type de cette dépendance spécifique, par exemple
$routeConfig
une dépendance de type\Magento\Framework\App\Route\ConfigInterface
.D'un autre côté,
di.xml
c'est l'endroit pour configurer les dépendances en utilisant des<preference/>
nœuds et / ou desxpath:type/arguments/argument
nœuds (parfois couplés à des nœuds de configuration plus avancés comme<virtualType/>
ou<proxy/>
). Configurer une dépendance signifie simplement mapper l'argument constructeur d'un objet à une implémentation / objet / béton .Vous voulez que les dépendances soient configurables via di.xml afin que vous puissiez les échanger et utiliser une implémentation différente pour une certaine interface ou un argument sous certaines conditions (continuez à lire l'exemple pour comprendre ce que certaines conditions sont censées signifier).
Par exemple, lorsque vous développez votre extension, vous devez d'abord créer une nouvelle classe (nous appelons cette nouvelle classe une implémentation ). Votre nouvelle classe implémente l'
\Magento\Framework\App\Route\ConfigInterface
interface et possède à l'intérieur de son corps une fonctionnalité concrète qui respecte le contrat d'interface. Commence maintenant la partie configuration : afin de dire à Magento d'utiliser votre implémentation nouvellement définie, vous devez configurer cette implémentation en tant que dépendance pour l'objetMagento\Backend\Model\Url
. Vous effectuez cette configuration à l'intérieur desdi.xml
fichiers ou de votre module. Dans ce cas, vous devez utiliser le<preference/>
nœud pour mapper l'interface à votre nouvelle implémentation. D'autres fois, vous utiliseriez lexpath:type/arguments/argument
di.xml
nœud plus granulaire pourmappez uniquement des arguments spécifiques (aka dépendances, aka interfaces) d'un concret à des implémentations spécifiques . Maintenant, votre implémentation ne sera active que comme dépendance pour l'objet\Magento\Backend\Model\Url
dans certaines conditions , par exemple, dans le flux d'exécution de code de la demande d'application actuelle, un objet de typeMagento\Backend\Model\Url
est en cours de création et il a besoin d'une implémentation pour la dépendance définie par le constructeur appelée$routeConfig
qui est de type\Magento\Framework\App\Route\ConfigInterface
.C'est un peu comme dire:
"Hey Mr. ObjectManager! Chaque fois qu'une instance d'objet de type
Magento\Backend\Model\Url
est demandée, veuillez d'abord regarder sa définition de constructeur de classe et analyser les dépendances qui y sont définies . Je veux que vous cherchiez ensuite à l'intérieur de la finale, fusionnéedi.xml
de la requête HTTP actuelle, la configuration pour chaque dépendance configurée qui est définie dans le Magento \ Backend \ Model \ Url constructeur de la classe . Vous me donnez que la mise en œuvre de la dépendance configurée « .la source