Não entendo por que, em algumas classes, suas injeções de dependência são declaradas duas vezes - uma vez no di.xml
construtor da classe concreta e no.
Por exemplo Magento\Backend\Model\Url
, em , di.xml
tem este conjunto de tipos para DI definido:
<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>
Mas, ao mesmo tempo, em sua classe concreta, as classes definidas em di.xml necessárias para injeção são declaradas novamente no construtor:
<?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 = []
) {
//...
}
?>
Se olharmos para o construtor acima \Magento\Framework\App\Route\ConfigInterface $routeConfig
, por exemplo, não está definido em di.xml
. Ele é definido apenas no construtor e o Magento ainda injeta o conteúdo routeConfig
na classe para uso, não é? Mesmo para \Magento\Framework\Encryption\EncryptorInterface $encryptor
e alguns outros.
Então, por que há uma necessidade de definir as outras injeções nos di.xml
construtores e no construtor quando ter essas declarações no construtor é suficiente para o Magento injetar essas dependências na classe para uso?
É importante entender a diferença entre definição de dependências e configuração de dependências.
As dependências não são definidas no di.xml. As dependências são definidas dentro do construtor da respectiva classe, especificando uma interface, um resumo ou uma fábrica como o tipo dessa dependência específica, por exemplo,
$routeConfig
é uma dependência do tipo\Magento\Framework\App\Route\ConfigInterface
.Por outro lado,
di.xml
é o local para configurar as dependências usando<preference/>
nós e / ouxpath:type/arguments/argument
nós (às vezes combinados com nós de configuração mais avançados, como<virtualType/>
ou<proxy/>
). Configurar uma dependência significa simplesmente mapear o argumento construtor de um objeto para uma implementação / objeto / concreto .Você deseja que as dependências sejam configuráveis via di.xml, para poder trocá-las e usar uma implementação diferente para uma determinada interface ou argumento sob certas condições (continue lendo o exemplo para entender o que determinadas condições devem significar).
Por exemplo, ao desenvolver sua extensão, você primeiro criaria uma nova classe (chamamos essa nova classe de implementação ). Sua nova classe implementa a
\Magento\Framework\App\Route\ConfigInterface
interface e possui em seu corpo uma funcionalidade concreta que respeita o contrato da interface. Agora começa a parte da configuração : para dizer ao Magento para usar sua implementação recém-definida, você deve configurá-la como uma dependência para o objetoMagento\Backend\Model\Url
. Você faz essa configuração dentro dosdi.xml
arquivos ou do seu módulo. Nesse caso, você precisa usar o<preference/>
nó para mapear a interface para sua nova implementação. Outras vezes, você usaria oxpath:type/arguments/argument
di.xml
nó mais granular paramapeie apenas argumentos específicos (também conhecidos como dependências, também conhecidos como interfaces) de um concreto para implementações específicas . Agora, sua implementação estará ativa apenas como uma dependência para o objeto\Magento\Backend\Model\Url
em determinadas condições , por exemplo, no fluxo de execução de código da solicitação de aplicativo atual, um objeto do tipoMagento\Backend\Model\Url
está sendo criado e precisa de uma implementação para a dependência definida pelo construtor chamada$routeConfig
qual é de tipo\Magento\Framework\App\Route\ConfigInterface
.É como dizer:
"Ei, Sr. ObjectManager! Sempre que uma instância de objeto do tipo
Magento\Backend\Model\Url
for solicitada, verifique primeiro a definição do construtor de classe e analise as dependências definidas nela. Quero que você procure dentro da final, mescladadi.xml
da solicitação HTTP atual, a configuração para cada dependência configurado que está definido no construtor da classe Magento \ backend \ Modelo \ Url . Você me dá que configurado implementação dependência ".fonte