왜 일부 클래스는 생성자와 di.xml에서 주입을 정의합니까?


12

일부 클래스에서 종속성 주입이 di.xml구체적인 클래스의 생성자에서 한 번 두 번 선언되는 이유를 이해하지 못합니다 .

에서 예를 들어 Magento\Backend\Model\Url, 자사는 di.xmlDI를위한 유형의 집합이 정의 :

<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>

그러나 동시에 구체적인 클래스에서 주입에 필요한 di.xml에 정의 된 클래스는 생성자에서 다시 선언됩니다.

<?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 = []
) {
    //...
}
?>

\Magento\Framework\App\Route\ConfigInterface $routeConfig예를 들어, 위의 생성자를 보면에 정의되어 있지 않습니다 di.xml. 그것은 생성자에서만 정의되며 Magento는 여전히 routeConfig클래스를 사용하기 위해 주입 합니다. 동일 \Magento\Framework\Encryption\EncryptorInterface $encryptor하고 몇 가지 다른.

그렇다면 di.xmlMagento가 클래스에 이러한 의존성을 주입하기에 생성자에 선언이 충분할 때 생성자와 생성자 에 다른 주입을 정의해야하는 이유는 무엇입니까?

답변:


15

Magento 2 의 설명서에 명시된대로di.xml 다음을 수행하는 데 사용할 수 있습니다.

di.xml인수 노드에서 클래스 생성자 인수를 구성 할 수 있습니다 . 객체 관리자는 생성하는 동안 이러한 인수를 클래스에 삽입합니다. XML 파일에 구성된 인수의 이름은 구성된 클래스의 생성자에있는 매개 변수의 이름과 일치해야합니다.

귀하의 경우에는 약간 복잡합니다. 각 인수를 하나씩 설명하겠습니다.

  • \Magento\Framework\App\Route\ConfigInterface $routeConfig: 이것은 인터페이스이므로 직접 사용할 수 없습니다 . 이 클래스app/etc/di.xml환경 설정이 정의되어 있으며 Magento\Framework\App\Route\Config클래스입니다.
  • \Magento\Framework\App\RequestInterface $request :이 클래스에도 동일하게 적용됩니다. Magento\Framework\App\Request\Http
  • \Magento\Framework\Url\SecurityInfoInterface $urlSecurityInfo: Magento\Framework\Url\SecurityInfo\Proxy기본 설정 과 동일한 사례가 여기에 있습니다.
  • \Magento\Framework\Url\ScopeResolverInterface $scopeResolver: 여기에서 우리는 재미있는 비트로 시작합니다. 에서 app/etc/di.xml환경 설정이 인터페이스에 대해 정의 그리고 그것은이다 Magento\Framework\Url\ScopeResolver클래스입니다. 그러나 Magento\Backend\Model\UrlMagento 2의 경우 다른 클래스를 사용해야하므로 di.xml게시 한 클래스 중 사용할 클래스를 정의합니다 Magento\Backend\Model\Url\ScopeResolver.
  • \Magento\Framework\Session\Generic $session 이것은 정상적인 클래스이므로 그대로 사용할 수 있습니다.
  • \Magento\Framework\Session\SidResolverInterface $sidResolver: 인터페이스로 돌아가서 기본 설정은 여전히 ​​정의되어 app/etc/di.xml있으며Magento\Framework\Session\SidResolver\Proxy
  • \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolverFactory : 팩토리 클래스이므로 그대로 사용할 수 있습니다.
  • \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver: 다시 우리 app/etc/di.xml와 선호는Magento\Framework\Url\QueryParamsResolver
  • \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig: ** 여기에 환경 설정이 정의되어있는 다른 경우 app/etc/di.xmlMagento\Framework\App\Config있습니다.
  • $scopeType: 여기에 클래스가없는 변수 만 있습니다. 모듈 은이 변수의 값으로 사용해야한다고 di.xml지정 Magento\Store\Model\ScopeInterface::SCOPE_STORE합니다. **
  • \Magento\Backend\Helper\Data $backendHelper: 여기서 우리는 그 클래스를 그대로 사용할 수 있습니다. 그러나이 클래스가 반드시 사용되는 것은 아니기 때문에 여기에 프록시가 사용됩니다 (프록시 클래스에 대한 자세한 내용은이 게시물을 참조하십시오. 마 젠토 2 : 프록시 클래스가 무엇인지에 대한 실제 설명? )
  • \Magento\Backend\Model\Menu\Config $menuConfig :이 클래스를 그대로 사용할 수 있습니다.
  • \Magento\Framework\App\CacheInterface $cache: app/etc/di.xml이 인터페이스 에 대해 정의 된 또 다른 환경 설정Magento\Framework\App\Cache\Proxy
  • \Magento\Backend\Model\Auth\Session $authSession: 여기에서도 마찬가지로 클래스를 사용할 수 있었지만 지연 로딩 대신 프록시 클래스를 사용합니다.
  • \Magento\Framework\Encryption\EncryptorInterface $encryptor: app/etc/di.xml다시 점프 하고 우리 Magento\Framework\Encryption\Encryptor는 선호로 찾습니다
  • \Magento\Store\Model\StoreFactory $storeFactory : 공장에서 사용할 수 있습니다.
  • \Magento\Framework\Data\Form\FormKey $formKey: 여기서 Magento\Framework\Data\Form\FormKey\Proxy지연 로딩을 위해 프록시 클래스를 다시 사용합니다 .
  • array $data = []: 이것은 항상 마지막에 오며 자동으로 빈 배열로 기본 설정됩니다. 여기에서 자세한 정보를 찾을 수 있습니다. 마 젠토 2 : $ data array constructor 매개 변수 란 무엇입니까?

요약

전 세계적으로 클래스 생성자 매개 변수는 인터페이스 또는 인스턴스화 할 수없는 클래스입니다. 따라서 di.xml각 클래스 생성자에 사용하려는 종속성을 조정할 수 있습니다. 인스턴스화 가능한 클래스에도 유효합니다. 예를 들어 제품 클래스를 생성자 인수로 사용하는 클래스 생성자가 있습니다. 구성 가능한 제품 모듈에 맞게 조정할 수 있으므로 구성 가능한 제품 클래스를 인수로 사용합니다.


인터페이스 매개 변수에 항상 환경 설정이 필요합니까? 폴백으로 볼 수 있습니까? 어디에서나 선호하지 않고 구성에서 구체적인 인수를 정의하는 것이 합리적입니까? 아니면 불가능합니까?
robsch

6

종속성 정의 와 종속성 구성 의 차이점을 이해하는 것이 중요합니다 .

종속성은 di.xml 내에 정의되어 있지 않습니다. 가 종속되어 생성자 내에 정의 된 인터페이스, 추상 또는 공장 등의 지정에 의해, 각 클래스의 유형 이 특정의 실행 종속 예하기의 $routeConfig타입의 의존성이다 \Magento\Framework\App\Route\ConfigInterface.

한편, di.xml종속 구성 할 수있는 장소입니다 사용하여 <preference/>노드 및 / 또는 xpath:type/arguments/argument노드를 (때로는 같은 고급 구성 노드와 결합 <virtualType/>또는 <proxy/>). 의존성을 구성한다는 것은 단순히 객체의 생성자 인수를 implementation / object / concrete에 매핑하는 것을 의미 합니다 .

di.xml을 통해 종속성을 구성하여 특정 조건에서 특정 인터페이스 또는 인수 대해 다른 구현 을 사용할 수 있도록 종속성을 구성 하고자 합니다 (예를 계속 읽고 특정 조건이 무엇을 의미하는지 이해하십시오).

예를 들어, 확장을 개발할 때 먼저 새 클래스를 작성합니다 (이 새 클래스를 구현이라고합니다 ). 새로운 클래스는 \Magento\Framework\App\Route\ConfigInterface인터페이스를 구현 하고 인터페이스 계약을 존중하는 구체적인 기능을 몸 안에 가지고 있습니다. 이제 구성 부분을 시작하십시오 . Magento가 새로 정의 된 구현을 사용 하도록 하려면 이 구현을 개체에 대한 종속성으로 구성 해야 합니다Magento\Backend\Model\Url . 파일 또는 모듈 내 에서이 구성을 수행 di.xml하십시오. 이 경우 <preference/>노드 를 사용 하여 인터페이스를 새 구현에 맵핑해야합니다. 다른 경우에는보다 세부적인 xpath:type/arguments/argument di.xml노드를 사용하여구체적인 구현의 특정 인수 (일명 종속성, 일명 인터페이스) 만 매핑합니다 . 이제 구현 만 활성화 할 개체에 대한 종속성으로 \Magento\Backend\Model\Url 특정 조건의 유형의 객체가 현재 어플리케이션 요청의 코드 실행 흐름이 예를 들어, Magento\Backend\Model\Url생성되고 그리고 그것은의 구현이 필요 생성자 정의 라는 의존성 $routeConfig인을 유형의 \Magento\Framework\App\Route\ConfigInterface.

그것은 말하는 것과 거의 같습니다.

"이봐, Mr. ObjectManager! 유형의 객체 인스턴스 Magento\Backend\Model\Url가 요청 될 때마다 먼저 클래스 생성자 정의를 살펴보고 거기에 정의 된 종속성을 분석하십시오 . 그런 다음 di.xml현재 HTTP 요청의 구성을 병합 한 최종 내부에서 조회하기를 원합니다. 각각의 모든에 대해 구성 종속 되어 정의젠토 \ 백엔드 \ 모델 \ URL 클래스 생성자 . 당신이 날 줄 것을 의존 구현을 구성했습니다. "

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.