Magento2如何生成特定的ExtensionFactory和ExtensionAttributeInterface?


28

我想使用扩展属性来解决问题,例如引用项目。
使用像Magento 1这样的设置类向这样的实体添加自定义属性没有问题,这不是这个问题。
现在,当我想公开由扩展程序通过实体API添加的属性作为扩展属性时,魔术使我不知所措。

更新我知道常规工厂是如何生成的。这个问题是关于特殊工厂的,这些工厂为生成的扩展属性接口实例化生成的实现。

这是我要使其正常工作所采取的步骤。我要添加这些内容,因此无论是谁尝试回答,都无需赘述。
我的问题是如何为何它的工作原理。

通过实体API公开扩展属性的步骤:

  1. 创建一个etc/extension_attributes.xml将属性添加到实体接口的
  2. 创建一个插件以将属性值添加到实体ExtensionAttributes实例。

为了做第二点,ExtensionAttributes需要实体实例。因此,插件依赖于工厂,对象管理器通过DI提供该工厂。

对于报价项目Magento\Quote\Api\Data\CartItemExtensionFactory,必须使用示例。
我猜想工厂的类型一定是引发魔力的触发器。

然后,Magento \Magento\Quote\Api\Data\CartItemExtensionInterface用所有扩展属性的设置器和获取器生成匹配接口。
但是,它似乎并未为该接口生成具体的实现。至少,PHPStorm没有看到它。

Magento如何收集生成类所需的信息?如何在具体实例上调用生成的接口方法?它是仅在内存中生成的类吗?

我很高兴它能奏效,但这并不能令人满意。Magentos使用扩展自动创建的属性的能力是其成功的关键因素。作为模块开发人员,我相信我需要对整个过程有透彻的了解。
如果我有时间,我自己会自己研究一下,但是我希望能得到一个解释。

更新2:花一点时间阅读\Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator和阅读\Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator。现在我至少有一个大概的想法。如果没有人击败我,我将在某一时间写一个完整的过程的描述,因为我认为这将是一个有用的参考。


2
Vinai ..问了一个问题..Omg
Amit Bera

Answers:


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. Autoloader无法实例化类并在此处初始化代码生成 \Magento\Framework\Code\Generator\Autoloader::load
  2. 然后将类后缀确定为Factory(可以在此处找到所有已声明后缀的列表\Magento\Framework\ObjectManager\DefinitionFactory::getCodeGenerator),并使用相应的Factory generator生成器类(Magento\Framework\ObjectManager\Code\Generator\Factory)来生成缺少的工厂
  3. 所有自动生成的类始终基于其他类,在工厂的情况下,源类名称仅通过删除Factory后缀即可得出Magento\Quote\Api\Data\CartItemExtension。此类不存在,并且自动加载器会再次调用自动生成,但是这次是Extension类
  4. 现在后缀是Extension并且\Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator将用于生成此类
  5. 用于扩展类生成的源类的计算方式为Magento\Quote\Api\Data\CartItemInterface,它存在,并且扩展类已成功生成。但是,在尝试包含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

一个重要的注意事项是,di.xml因为Extension和ExtensionInterface都是自动生成的,所以没有对ExtensionInterface的偏好。这不是问题,因为预计不会通过构造直接注入ExtentionInterface。


@Vinai,不客气。谢谢,赏金令人惊讶。更新:仅供参考,如果悬赏是在接受答案后开始的,则不会自动授予。
Alex 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的函数

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.