Magento2は特定のExtensionFactoryおよびExtensionAttributeInterfaceをどのように生成しますか?


28

引用アイテムなどの拡張属性を使用して、頭を包み込みたいと思います。
Magento 1のようなセットアップクラスを使用して、このようなエンティティにカスタム属性を追加しても問題ありません。これはこの質問の目的ではありません。
現時点では、エンティティAPIを介して拡張機能によって拡張属性として追加されたこのような属性を公開したいときに、この魔法に圧倒されます。

更新通常のファクトリがどのように生成されるかを知っています。この質問は、生成された拡張属性インターフェースの生成された実装をインスタンス化する特別なファクトリーに関するものです。

これを機能させるために私がとるステップは次のとおりです。私はこれらを追加するので、答えようとする人は誰でもそれらの詳細に入る必要はありません。
私の質問はどのようにか、なぜそれが動作します。

エンティティAPIを介して拡張属性を公開する手順:

  1. etc/extension_attributes.xmlエンティティインターフェイスに属性を追加するを作成します
  2. エンティティExtensionAttributesインスタンスに属性値を追加するプラグインを作成します。

2番目のポイントを実行するには、エンティティExtensionAttributesインスタンスが必要です。このため、プラグインはファクトリに依存します。ファクトリは、オブジェクトマネージャがDIを介して提供します。

見積品目の例Magento\Quote\Api\Data\CartItemExtensionFactoryを使用する必要があります。
私はこの工場のタイプが何らかの形で生成魔法の引き金になっているに違いないと思います。

その後、Magentoは\Magento\Quote\Api\Data\CartItemExtensionInterface、すべての拡張属性のセッターとゲッターとの一致するインターフェースを生成します。
ただし、そのインターフェイスの具体的な実装は生成されないようです。少なくともPHPStormはそれを見ていません。

Magentoは、クラスを生成するために必要な情報をどのように収集しますか?生成されたインターフェイスメソッドは、具体的なインスタンスでどのように呼び出すことができますか?メモリのみで生成されるクラスですか?

私はそれが機能することを嬉しく思いますが、それは本当に満足のいくものではありません。拡張機能によって自動的に作成された属性を使用するMagentos機能は、その成功の重要な要因の1つです。モジュール開発者として、プロセス全体を完全に理解する必要があると思います。
時間があれば、自分でこれを掘り下げたいと思いますが、説明が得られればいいと思います。

UPDATE 2:通読するために少し時間がかかった\Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator\Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator。今、私は少なくとも何が起こっているのか大まかな考えを持っています。誰も私に勝てない場合、私はそれが有用な参考になると思うので、ある時点で完全なプロセスの説明を書きます。


2
The Vinaiは..質問をしました..Omg
Amit Bera

回答:


26

すべての自動生成の第一は、例えば、クラス名の接尾辞に基づいて起こっているFactoryExtensionInterface(参照\Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator::EXTENSION_INTERFACE_SUFFIX)またはExtension(参照します\Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator::EXTENSION_SUFFIX)。

ここでサフィックスに基づいて適切なジェネレータが選択されます\Magento\Framework\Code\Generator::generateClass

Magentoモードがdeveloperあり、欠落クラスがオンザフライで生成できると仮定しましょう(コンパイラーを使用すると同様のプロセスが発生します)。オブジェクトマネージャがインスタンス化しようとしたときにMagento\Quote\Api\Data\CartItemExtensionFactory、存在しないとすると、次のことが起こります。

  1. オートローダーはクラスのインスタンス化に失敗し、ここでコード生成を開始します \Magento\Framework\Code\Generator\Autoloader::load
  2. 次に、クラスサフィックスが決定されFactory(宣言されたすべてのサフィックスのリストはここにあります\Magento\Framework\ObjectManager\DefinitionFactory::getCodeGenerator)、対応するファクトリジェネレータクラス(Magento\Framework\ObjectManager\Code\Generator\Factory)を使用して、欠落しているファクトリを生成します
  3. すべての自動生成クラスは常に別のクラスに基づいています。ファクトリの場合、ソースクラス名はFactory接尾辞を削除するだけで計算されますMagento\Quote\Api\Data\CartItemExtension。このクラスは存在せず、オートローダーによってオートジェネレーションが再度呼び出されますが、今回はExtensionクラスの場合
  4. 今サフィックスがあるExtension\Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator、このクラスを生成するために使用されます
  5. Extensionクラス生成のソースクラスはとして計算されMagento\Quote\Api\Data\CartItemInterface、それが存在し、Extensionクラスが正常に生成されます。ただし、Extensionクラスファイルをインクルードしようとすると、Magento\Quote\Api\Data\CartItemExtensionimplements Magento\Quote\Api\Data\CartItemExtensionInterfaceが存在しないため、自動生成が再度トリガーされます
  6. サフィックスがあるExtensionInterface\Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator生成に使用されます
  7. ExtensionInterfaceおよびExtensionクラスはからの情報に基づいて生成されextension_attributes.xml、を介してアクセスでき\Magento\Framework\Api\ExtensionAttribute\Config、その後Factoryが生成されます

1つの重要な注意点は、di.xmlExtensionInterfaceとExtensionInterfaceの両方が自動生成されるため、ExtensionInterfaceの設定がないことです。ExtentionInterfaceは構造を介して直接注入されることは想定されていないため、これは問題ではありません。


@Vinaiどういたしまして。バウンティは素晴らしい驚きでした、ありがとう。更新:ちょうどFYI、回答が受け入れられた後に報奨金が開始された場合、自動的に授与されません。
アレックスPaliarush

0

私にとって、今夜、@ Alexからの答えに加えて、次の行を見ることができます。

$modelReflection = new \ReflectionClass($extensibleClassName);
        if ($modelReflection->isInterface()
            && $modelReflection->isSubclassOf(self::EXTENSIBLE_INTERFACE_NAME)
            && $modelReflection->hasMethod('getExtensionAttributes')
        ) {
            $this->classInterfaceMap[$extensibleClassName] = $extensibleClassName;
            return $this->classInterfaceMap[$extensibleClassName];
        }

クラスで \Magento\Framework\Api\ExtensionAttributesFactory

拡張インターフェイスが生成されていない場合にデバッグを開始する場合があります。拡張属性のほとんどは、Magento 2が期待するようにクラスを構造化することです。

これらの行は言っています:

  • extension_attributesのクラスはインターフェースです

  • \ Magento \ Framework \ Api \ ExtensibleDataInterfaceを拡張しますか

  • このインターフェイスにはgetExtensionAttributesという関数があります

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