Nie rozumiem, dlaczego w niektórych klasach ich zastrzyki zależności są deklarowane dwukrotnie - raz w di.xml
konstruktorze konkretnej klasy.
Na przykład w Magento\Backend\Model\Url
jego di.xml
zdefiniowano następujący zestaw typów dla 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>
Ale jednocześnie, w swojej konkretnej klasie, klasy zdefiniowane w pliku di.xml wymagane do wstrzyknięcia są ponownie deklarowane w konstruktorze:
<?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 = []
) {
//...
}
?>
Jeśli spojrzymy na jego konstruktor powyżej \Magento\Framework\App\Route\ConfigInterface $routeConfig
, na przykład nie jest zdefiniowany w di.xml
. Jest zdefiniowany tylko w konstruktorze, a Magento nadal będzie wprowadzał routeConfig
klasę do użytku, prawda? To samo dotyczy \Magento\Framework\Encryption\EncryptorInterface $encryptor
kilku innych.
Dlaczego więc istnieje potrzeba zdefiniowania innych zastrzyków zarówno di.xml
w konstruktorze, jak i w konstruktorze, skoro posiadanie tych deklaracji w konstruktorze jest wystarczające, aby Magento wstrzyknął te zależności do klasy w celu użycia?
Ważne jest zrozumienie różnicy między definicją zależności a konfiguracją zależności.
Zależności nie są zdefiniowane w pliku di.xml. Zależności są definiowane wewnątrz konstruktora odpowiedniej klasy poprzez określenie interfejsu, abstraktu lub fabryki jako typu tej konkretnej zależności, np.
$routeConfig
Jest zależnością typu\Magento\Framework\App\Route\ConfigInterface
.Z drugiej strony
di.xml
jest to miejsce do konfigurowania zależności za pomocą<preference/>
węzłów i / lubxpath:type/arguments/argument
węzłów (czasami w połączeniu z bardziej zaawansowanymi węzłami konfiguracji, takimi jak<virtualType/>
lub<proxy/>
). Konfiguracja zależności oznacza po prostu odwzorowanie argumentu konstruktora obiektu na implementację / obiekt / konkret .Chcesz, aby zależności były konfigurowalne za pomocą di.xml, dzięki czemu możesz je zamienić i użyć innej implementacji dla określonego interfejsu lub argumentu pod pewnymi warunkami (czytaj dalej przykład, aby zrozumieć, co pewne warunki powinny oznaczać).
Na przykład, opracowując rozszerzenie, najpierw należy utworzyć nową klasę (tę klasę nazywamy implementacją ). Twoja nowa klasa implementuje
\Magento\Framework\App\Route\ConfigInterface
interfejs i ma w sobie konkretną funkcjonalność, która honoruje umowę interfejsu. Teraz zaczyna się część konfiguracyjna : aby powiedzieć Magento, aby użyła nowo zdefiniowanej implementacji, musisz skonfigurować tę implementację jako zależność od obiektuMagento\Backend\Model\Url
. Wykonujesz tę konfigurację wdi.xml
plikach lub w module. W takim przypadku musisz użyć<preference/>
węzła, aby odwzorować interfejs na nową implementację. Innym razem używałbyś bardziej szczegółowegoxpath:type/arguments/argument
di.xml
węzła doodwzoruj tylko konkretne argumenty (aka zależności, aka interfejsy) konkretnego na konkretne implementacje . Teraz twoja implementacja będzie aktywna jako zależność dla obiektu tylko\Magento\Backend\Model\Url
w określonych warunkach , np. W przepływie wykonania kodu bieżącego żądania aplikacjiMagento\Backend\Model\Url
tworzony jest obiekt typu i potrzebuje on implementacji dla zdefiniowanej przez konstruktora zależności,$routeConfig
która nazywa się typu\Magento\Framework\App\Route\ConfigInterface
.To prawie tak, jakby powiedzieć:
„Hej, panie ObjectManager! Za każdym razem, gdy
Magento\Backend\Model\Url
żądana jest instancja typu obiektu, najpierw spójrz na definicję konstruktora klasy i przeanalizuj zdefiniowane w niej zależności . Chcę, abyś przejrzał wewnątrz końcowego, scalonegodi.xml
bieżącego żądania HTTP konfiguracji dla każdego skonfigurowanego zależność , która jest zdefiniowana w klasie konstruktora Magento \ Backend \ Modele \ Url . Dajesz mi , że skonfigurowany realizację zależności.”źródło