Como Magento2 gerar específico ExtensionFactory e ExtensionAttributeInterface?
-
19-12-2019 - |
Pergunta
Eu gostaria de envolver minha cabeça em torno usando atributos de extensão, por exemplo, para citar os itens.
Não há problema, adicionar um atributo personalizado a uma tal entidade utilizando um programa de configuração de classe, como no Magento 1, este não é o que esta pergunta é sobre.
No momento em que a magia apodera de mim quando eu quero expor tal atributo foi adicionado por uma extensão de via a entidades API como um atributo de extensão.
ATUALIZAÇÃO: Eu sei como regular fábricas são gerados.Esta pergunta é sobre o especial de fábricas que instanciar gerado implementações para a geração de atributo de extensão de interfaces.
Aqui estão os passos que devo tomar para fazê-lo funcionar.Estou adicionando esses portanto, quem tenta responder não precisa ir para os detalhes.
A minha pergunta é COMO ou POR ele funciona.
Passos para expor um atributo de extensão através de uma entidade de API:
- Criar um
etc/extension_attributes.xml
que adiciona o atributo de entidade de interface - Criar um plugin para adicionar o atributo de valor para as entidades
ExtensionAttributes
instância.
A fim de fazer o segundo ponto, as entidades ExtensionAttributes
instância é necessária.Por esta razão, o plugin depende de uma fábrica, que o objeto do gerenciador de suprimentos através de DI.
Para a cotação de item de exemplo Magento\Quote\Api\Data\CartItemExtensionFactory
tem de ser usado.
Eu acho que o tipo de fábrica de alguma forma, deve ser o gatilho para a geração de magia.
Magento, em seguida, gera a interface correspondente \Magento\Quote\Api\Data\CartItemExtensionInterface
com os setters e getters para todos os atributos de extensão.
No entanto, não parece gerar o concreto de implementação para essa interface.A concessão de PHPStorm não vê-lo.
Como Magento reunir as informações necessárias para gerar a classe?Como pode gerado métodos de interface de ser chamado em um exemplo concreto?É uma classe que apenas será gerado em memória apenas?
Eu estou feliz, ele funciona, mas que não é realmente satisfatório.Magentos capacidade para utilizar os atributos criados automaticamente por extensões é um fator chave para o seu sucesso.Como um desenvolvedor de módulos, eu acredito que eu preciso de uma profunda compreensão de todo o processo.
Devo ter tempo eu tinha acabado de cavar esta me, mas eu preferiria que se eu só podia ter uma explicação.
ATUALIZAÇÃO 2:Levou um pouco de tempo para ler \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator
e \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator
.Agora eu, pelo menos, ter uma idéia do que está acontecendo.Se ninguém bate-me a ele, eu vou escrever uma descrição de todo o processo em um ponto, como eu acho que deveria ser uma referência útil.
Solução
Primeiro de tudo auto-geração está acontecendo com base na classe de sufixo de nome, exemplo: Factory
, ExtensionInterface
(ver \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator::EXTENSION_INTERFACE_SUFFIX
) ou Extension
(ver \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator::EXTENSION_SUFFIX
).
Adequada do gerador é selecionado com base no sufixo aqui \Magento\Framework\Code\Generator::generateClass
.
Vamos supor que o Magento é o modo de developer
e faltam às aulas pode ser gerado em voar (processo semelhante acontece quando é utilizado o compilador).Quando o gerenciador de objetos tenta instanciar vamos dizer Magento\Quote\Api\Data\CartItemExtensionFactory
e ele não existe, acontece o seguinte:
- Autoloader falha ao criar uma instância da classe e inicia a geração de código aqui
\Magento\Framework\Code\Generator\Autoloader::load
- Em seguida, sufixo de classe é determinada como
Factory
(lista de todos os declarado sufixos podem ser encontradas aqui\Magento\Framework\ObjectManager\DefinitionFactory::getCodeGenerator
) e correspondente Fábrica gerador de classe (Magento\Framework\ObjectManager\Code\Generator\Factory
) é usado para gerar falta de fábrica - Todas as classes são geradas automaticamente sempre com base em outro classes, no caso de fábrica, origem do nome da classe é calculado apenas removendo
Factory
sufixo, seráMagento\Quote\Api\Data\CartItemExtension
.Esta classe não existe e auto-geração é chamado uma vez por autoloader, mas desta vez para a classe de Extensão - Agora, o sufixo é
Extension
e\Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator
será utilizado para gerar esta classe - Classe de origem para a classe de Extensão geração é calculado como
Magento\Quote\Api\Data\CartItemInterface
, ele existe e Extensão de classe é criado com êxito.No entanto, na tentativa de incluir a Extensão do arquivo de classe, geração automática é acionado mais uma vez, devidoMagento\Quote\Api\Data\CartItemExtension
implementaMagento\Quote\Api\Data\CartItemExtensionInterface
, que não existe - Sufixo é
ExtensionInterface
e\Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator
será utilizado para a geração de - ExtensionInterface e classes de Extensão são gerados com base em informações de
extension_attributes.xml
, acessível através de\Magento\Framework\Api\ExtensionAttribute\Config
, e , em seguida, a Fábrica será gerado
Uma observação importante é que não há preferência por ExtensionInterface em di.xml
porque tanto a Extensão e ExtensionInterface são gerados automaticamente.Este não é um problema porque ExtentionInterface não é esperado para ser injetado através construir diretamente.
Outras dicas
Para mim, esta noite, em cima da resposta de @Alex, eu posso ver as linhas
$modelReflection = new \ReflectionClass($extensibleClassName);
if ($modelReflection->isInterface()
&& $modelReflection->isSubclassOf(self::EXTENSIBLE_INTERFACE_NAME)
&& $modelReflection->hasMethod('getExtensionAttributes')
) {
$this->classInterfaceMap[$extensibleClassName] = $extensibleClassName;
return $this->classInterfaceMap[$extensibleClassName];
}
na classe de \Magento\Framework\Api\ExtensionAttributesFactory
são, onde se pretende iniciar a depuração se a interface de extensão não está sendo gerado.Muito bonito atributos de extensão é sobre a estruturação de nossa classe como o Magento 2 vai esperar.
estas linhas estão dizendo:
é a classe no nosso extension_attributes uma interface
ele se estende \Magento\Framework\Api\ExtensibleDataInterface
tem esta interface de uma função chamada getExtensionAttributes