Eu gostaria de entender os atributos de extensão, por exemplo, para itens de cotação.
Não há problema em adicionar um atributo personalizado a uma entidade usando uma classe de instalação como no Magento 1, não é sobre isso que se trata.
No momento, a mágica me impressiona quando quero expor um atributo que foi adicionado por uma extensão por meio da API de entidades como um atributo de extensão.
ATUALIZAÇÃO : Eu sei como as fábricas regulares são geradas. Esta pergunta é sobre as fábricas especiais que instanciam as implementações geradas para as interfaces de atributo de extensão geradas.
Aqui estão os passos que eu tomo para fazê-lo funcionar. Estou adicionando esses itens para que quem tente responder não precise entrar nesses detalhes.
A minha pergunta é COMO ou POR QUE funciona.
Etapas para expor um atributo de extensão por meio de uma API da entidade:
- Crie um
etc/extension_attributes.xml
que adicione o atributo à interface da entidade - Crie um plug-in para adicionar o valor do atributo à
ExtensionAttributes
instância de entidades .
Para fazer o segundo ponto, a ExtensionAttributes
instância de entidades é necessária. Por esse motivo, o plug-in depende de uma fábrica, que o gerenciador de objetos fornece via DI.
Para o item de cotação, o exemplo Magento\Quote\Api\Data\CartItemExtensionFactory
deve ser usado.
Eu acho que o tipo dessa fábrica de alguma forma deve ser o gatilho para a geração mágica.
O Magento gera a interface correspondente \Magento\Quote\Api\Data\CartItemExtensionInterface
com os setters e getters para todos os atributos de extensão.
No entanto, parece não gerar a implementação concreta para essa interface. No momento, o PHPStorm não está vendo.
Como o Magento coleta as informações necessárias para gerar a classe? Como os métodos de interface gerados podem ser chamados em uma instância concreta? É uma classe que é gerada apenas na memória?
Estou feliz que funcione, mas isso não é realmente satisfatório. A capacidade do Magentos de usar atributos criados automaticamente por extensões é um fator chave para seu sucesso. Como desenvolvedor de módulos, acredito que preciso de um entendimento completo de todo o processo.
Se eu tivesse tempo, eu mesmo iria me aprofundar nisso, mas preferiria se pudesse obter uma explicação.
ATUALIZAÇÃO 2 : Demorou um pouco para ler \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator
e ler \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator
. Agora, pelo menos, tenho uma ideia aproximada do que está acontecendo. Se ninguém me bater, escreverei uma descrição do processo completo em um ponto, pois acho que seria uma referência útil.
Respostas:
Antes de tudo, a geração automática está acontecendo com base no sufixo do nome da classe, por exemplo
Factory
,ExtensionInterface
(consulte\Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator::EXTENSION_INTERFACE_SUFFIX
) ouExtension
(consulte\Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator::EXTENSION_SUFFIX
).O gerador apropriado é selecionado com base no sufixo aqui
\Magento\Framework\Code\Generator::generateClass
.Vamos assumir que o modo Magento está
developer
e as classes ausentes podem ser geradas em tempo real (processos semelhantes acontecerão quando o compilador for usado). Quando o gerenciador de objetos tenta instanciar, digamos,Magento\Quote\Api\Data\CartItemExtensionFactory
e ele não existe, acontece o seguinte:\Magento\Framework\Code\Generator\Autoloader::load
Factory
(a lista de todos os sufixos declarados pode ser encontrada aqui\Magento\Framework\ObjectManager\DefinitionFactory::getCodeGenerator
) e a classe do gerador de Fábrica correspondente (Magento\Framework\ObjectManager\Code\Generator\Factory
) é usada para gerar a falta de fábricaFactory
sufixoMagento\Quote\Api\Data\CartItemExtension
. Essa classe não existe e a geração automática é invocada mais uma vez pelo carregador automático, mas desta vez para a classe ExtensionExtension
e\Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator
será usado para gerar esta classeMagento\Quote\Api\Data\CartItemInterface
existe e a classe de extensão é gerada com êxito. No entanto, na tentativa de incluir o arquivo da classe Extension, a geração automática é acionada mais uma vez porqueMagento\Quote\Api\Data\CartItemExtension
implementaMagento\Quote\Api\Data\CartItemExtensionInterface
, o que não existeExtensionInterface
e\Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator
será usado para geraçãoextension_attributes.xml
, acessíveis via e\Magento\Framework\Api\ExtensionAttribute\Config
, em seguida, o Factory é geradoUma observação importante é que não há preferência pelo ExtensionInterface
di.xml
porque o Extension e o ExtensionInterface são gerados automaticamente. Isso não é um problema porque não se espera que ExtentionInterface seja injetado diretamente através da construção.fonte
Para mim, hoje à noite, além da resposta de @Alex, posso ver as linhas
na aula
\Magento\Framework\Api\ExtensionAttributesFactory
é onde podemos começar a depurar se a interface de extensão não estiver sendo gerada. Praticamente os atributos de extensão são sobre a estruturação de nossa classe, como o Magento 2 espera.
estas linhas estão dizendo:
é a classe em nossa extension_attributes uma interface
estende \ Magento \ Framework \ Api \ ExtensibleDataInterface
possui nessa interface uma função chamada getExtensionAttributes
fonte