Ich verstehe nicht, warum in einigen Klassen ihre Abhängigkeitsinjektionen zweimal deklariert werden - einmal im di.xml
und im Konstruktor der konkreten Klasse.
Zum Beispiel in Magento\Backend\Model\Url
, der di.xml
hat diesen Satz von Typen für DI definiert:
<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>
Gleichzeitig werden in der konkreten Klasse die in di.xml definierten Klassen, die für die Injektion erforderlich sind, im Konstruktor erneut deklariert:
<?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 = []
) {
//...
}
?>
Wenn wir uns den Konstruktor oben ansehen, \Magento\Framework\App\Route\ConfigInterface $routeConfig
ist er beispielsweise nicht in definiert di.xml
. Es ist nur im Konstruktor definiert und Magento wird das weiterhin routeConfig
zur Verwendung in die Klasse einfügen, nicht wahr? Gleiches gilt für \Magento\Framework\Encryption\EncryptorInterface $encryptor
und einige andere.
Warum müssen dann die anderen Injektionen in beiden di.xml
und im Konstruktor definiert werden, wenn diese Deklarationen im Konstruktor ausreichen, damit Magento diese Abhängigkeiten zur Verwendung in die Klasse einfügt?
Es ist wichtig, den Unterschied zwischen der Definition von Abhängigkeiten und der Konfiguration von Abhängigkeiten zu verstehen .
Abhängigkeiten sind in di.xml nicht definiert. Abhängigkeiten werden innerhalb des Konstruktors der jeweiligen Klasse definiert, indem eine Schnittstelle, eine Zusammenfassung oder eine Factory als Typ dieser spezifischen Abhängigkeit angegeben wird, z. B.
$routeConfig
eine Abhängigkeit vom Typ\Magento\Framework\App\Route\ConfigInterface
.Auf der anderen Seite können Sie
di.xml
die Abhängigkeiten mithilfe von<preference/>
Knoten und / oderxpath:type/arguments/argument
Knoten konfigurieren (manchmal gekoppelt mit erweiterten Konfigurationsknoten wie<virtualType/>
oder<proxy/>
). Das Konfigurieren einer Abhängigkeit bedeutet einfach, das Konstruktorargument eines Objekts einer Implementierung / einem Objekt / einem Beton zuzuordnen .Sie möchten, dass Abhängigkeiten über di.xml konfiguriert werden können, damit Sie sie austauschen und unter bestimmten Bedingungen eine andere Implementierung für eine bestimmte Schnittstelle oder ein bestimmtes Argument verwenden können (lesen Sie das Beispiel weiter, um zu verstehen, was bestimmte Bedingungen bedeuten sollen).
Wenn Sie beispielsweise Ihre Erweiterung entwickeln, erstellen Sie zuerst eine neue Klasse (wir nennen diese neue Klasse eine Implementierung ). Ihre neue Klasse implementiert die
\Magento\Framework\App\Route\ConfigInterface
Schnittstelle und verfügt in ihrem Körper über eine konkrete Funktionalität, die den Schnittstellenvertrag einhält. Jetzt beginnt der Konfigurationsteil : Um Magento anzuweisen, Ihre neu definierte Implementierung zu verwenden, müssen Sie diese Implementierung als Abhängigkeit für das Objekt konfigurierenMagento\Backend\Model\Url
. Sie führen diese Konfiguration in dendi.xml
Dateien oder in Ihrem Modul durch. In diesem Fall müssen Sie den<preference/>
Knoten verwenden, um die Schnittstelle Ihrer neuen Implementierung zuzuordnen. In anderen Fällen würden Sie den detaillierterenxpath:type/arguments/argument
di.xml
Knoten verwendenOrdnen Sie nur bestimmte Argumente (auch bekannt als Abhängigkeiten, auch bekannt als Schnittstellen) eines Betons bestimmten Implementierungen zu . Nun wird Ihre Implementierung nur dann aktiv sein , als eine Abhängigkeit für das Objekt\Magento\Backend\Model\Url
unter bestimmten Bedingungen , beispielsweise in dem Codeausführungsablauf der aktuellen Anwendungsanforderung ein Objekt vom TypMagento\Backend\Model\Url
erstellt wird , und es muss eine Implementierung für den Konstruktor definierte Abhängigkeit genannt ,$routeConfig
die ist vom Typ\Magento\Framework\App\Route\ConfigInterface
.Es ist so ziemlich so, als würde man sagen:
"Hey Mr. ObjectManager! Wenn eine Objektinstanz vom Typ
Magento\Backend\Model\Url
angefordert wird, schauen Sie sich bitte zuerst die Definition des Klassenkonstruktors an und analysieren Sie die definierten Abhängigkeiten darin . Ich möchte, dass Sie dann in der endgültigen, zusammengeführten,di.xml
aktuellen HTTP-Anforderung die Konfiguration für jede konfigurierte Abhängigkeit , die im Klassenkonstruktor Magento \ Backend \ Model \ Url definiert ist . Sie geben mir diese konfigurierte Abhängigkeitsimplementierung. "quelle