一部のクラスがコンストラクタとdi.xmlの両方で注入を定義するのはなぜですか?


12

一部のクラスで、依存関係の注入が2回宣言されている理由がわかりません。1回目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ファイルで構成された引数の名前は、構成されたクラスのコンストラクターのパラメーターの名前に対応している必要があります。

あなたのケースでは少し複雑ですが、各引数を1つずつ説明します。

  • \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:ここでは、興味深い部分から始めます。優先このインタフェース用に定義され、それがであるクラス。ただし、Magento 2は別のクラスを使用する必要があるため、投稿したクラスのうちどれが使用されるかを定義しますapp/etc/di.xmlMagento\Framework\Url\ScopeResolverMagento\Backend\Model\Urldi.xmlMagento\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.xmlている別のケースですMagento\Framework\App\Config
  • $scopeType:ここでは、変数の前にクラスがありません。モジュールdi.xmlは、それMagento\Store\Model\ScopeInterface::SCOPE_STOREをこの変数の値として使用するように指定しています。**
  • \Magento\Backend\Helper\Data $backendHelper:ここでは、そのクラスをそのまま使用できます。ただし、このクラスは必ずしも使用されているわけではないため、ここではプロキシが使用されています(プロキシクラスの詳細については、この投稿を参照してください:Magento 2:プロキシクラスとは何かの実際的な説明?
  • \Magento\Backend\Model\Menu\Config $menuConfig :このクラスをそのまま使用できます。
  • \Magento\Framework\App\CacheInterface $cacheapp/etc/di.xmlこのインターフェース用に定義されている別の設定で、Magento\Framework\App\Cache\Proxy
  • \Magento\Backend\Model\Auth\Session $authSessionここでも同じですが、クラスをそのまま使用することもできますが、遅延読み込みの代わりにプロキシクラスを使用します。
  • \Magento\Framework\Encryption\EncryptorInterface $encryptorapp/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 = []:これは常に最後に来て、自動的に空の配列にデフォルトで設定されます。ここで詳細を確認できます:Magento 2:$ data配列コンストラクターパラメーターとは何ですか?

要約する

グローバルに、クラスコンストラクターのパラメーターは、インターフェイスまたはインスタンス化できないクラスです。したがってdi.xml、各クラスコンストラクターに使用する依存関係を調整できます。また、インスタンス化可能なクラスにも有効です。たとえば、コンストラクターの引数として製品クラスを取るクラスコンストラクター。構成可能な製品モジュールで調整できるため、代わりに構成可能な製品クラスを引数として使用します。


インターフェイスパラメータには常に設定が必要ですか?フォールバックと見なすことができますか?設定をどこにも設定せずに、構成で具体的な引数を定義するだけでも意味がありますか?それとも不可能ですか?
robsch

6

依存関係の定義と依存関係の構成の違いを理解することが重要です。

依存関係はdi.xml内では定義されません。依存関係は、特定の依存関係のタイプとしてインターフェイス、抽象、またはファクトリを指定することにより、それぞれのクラスのコンストラクタ内で定義されます。たとえば、typeの依存関係です。$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

それは言うこととほとんど同じです:

「Hey Mr. ObjectManager!タイプのオブジェクトインスタンスMagento\Backend\Model\Urlが要求されたときはいつでも、まずそのクラスコンストラクター定義を見て、そこで定義されている依存関係を分析してください。次にdi.xml、現在のHTTP要求のマージされた最後の構成内を検索してください。一人ひとりのために構成された依存されて定義された中でMagentoの\バックエンド\モデル\ URLクラスのコンストラクタ。あなたは私を与えることに依存の実装を構成しました。」

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.