Bagaimana Magento2 menghasilkan ExtensionFactory dan ExtensionAttributeInterface spesifik?

28

Saya ingin membungkus kepala saya menggunakan atribut ekstensi, misalnya untuk item kutipan.
Tidak ada masalah menambahkan atribut khusus ke entitas seperti itu menggunakan kelas penyetelan seperti di Magento 1, ini bukan tentang pertanyaan ini.
Saat ini keajaiban menguasai saya ketika saya ingin mengekspos atribut yang ditambahkan oleh ekstensi melalui entitas API sebagai atribut ekstensi.

UPDATE : Saya tahu bagaimana pabrik biasa dihasilkan. Pertanyaan ini adalah tentang pabrik khusus yang memberi contoh implementasi yang dihasilkan untuk antarmuka atribut ekstensi yang dihasilkan.

Inilah langkah-langkah yang saya ambil untuk membuatnya bekerja. Saya menambahkan ini sehingga siapa pun yang mencoba menjawab tidak perlu masuk ke detail itu.
Pertanyaan saya adalah BAGAIMANA atau MENGAPA berfungsi.

Langkah-langkah untuk mengekspos atribut ekstensi melalui API entitas:

  1. Buat etc/extension_attributes.xmlyang menambahkan atribut ke antarmuka entitas
  2. Buat plugin untuk menambahkan nilai atribut ke ExtensionAttributesinstance entitas .

Untuk melakukan poin kedua, ExtensionAttributesinstance entitas diperlukan. Untuk alasan ini plugin bergantung pada pabrik, yang disediakan oleh manajer objek melalui DI.

Untuk contoh item kutipan Magento\Quote\Api\Data\CartItemExtensionFactoryharus digunakan.
Saya kira jenis pabrik ini entah bagaimana harus menjadi pemicu sihir generasi.

Magento kemudian menghasilkan antarmuka yang cocok \Magento\Quote\Api\Data\CartItemExtensionInterfacedengan setter dan getter untuk semua atribut ekstensi.
Namun, sepertinya tidak menghasilkan implementasi konkret untuk antarmuka itu. Setidaknya PHPStorm tidak melihatnya.

Bagaimana Magento mengumpulkan informasi yang diperlukan untuk menghasilkan kelas? Bagaimana metode antarmuka yang dihasilkan dapat dipanggil pada contoh konkret? Apakah ini kelas yang hanya dihasilkan dalam memori saja?

Saya senang itu berhasil, tapi itu tidak terlalu memuaskan. Kemampuan Magentos untuk menggunakan atribut yang dibuat secara otomatis oleh ekstensi adalah salah satu faktor kunci keberhasilannya. Sebagai pengembang modul, saya percaya saya perlu pemahaman menyeluruh tentang keseluruhan proses.
Jika saya punya waktu saya akan menggali sendiri, tetapi saya lebih suka jika saya bisa mendapatkan penjelasan.

UPDATE 2 : Butuh sedikit waktu untuk membaca \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGeneratordan \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator. Sekarang setidaknya saya punya ide kasar apa yang sedang terjadi. Jika tidak ada yang mengalahkan saya untuk itu saya akan menulis deskripsi proses penuh pada satu titik, karena saya pikir itu akan menjadi referensi yang bermanfaat.

Vinai
sumber
2
apakah The Vinai .. mengajukan pertanyaan .. Omg
Amit Bera

Jawaban:

26

Pertama-tama autogenerasi terjadi berdasarkan akhiran nama kelas, misalnya Factory, ExtensionInterface(lihat \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator::EXTENSION_INTERFACE_SUFFIX) atau Extension(lihat \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator::EXTENSION_SUFFIX).

Generator yang tepat dipilih berdasarkan akhiran di sini \Magento\Framework\Code\Generator::generateClass.

Mari kita asumsikan mode Magento adalah developerdan kelas yang hilang dapat dihasilkan dengan cepat (proses serupa akan terjadi ketika kompiler digunakan). Ketika manajer objek mencoba membuat instance katakanlah Magento\Quote\Api\Data\CartItemExtensionFactorydan itu tidak ada, berikut ini terjadi:

  1. Autoloader gagal untuk membuat instance kelas dan memulai pembuatan kode di sini \Magento\Framework\Code\Generator\Autoloader::load
  2. Kemudian akhiran kelas ditentukan sebagai Factory(daftar semua akhiran yang dideklarasikan dapat ditemukan di sini \Magento\Framework\ObjectManager\DefinitionFactory::getCodeGenerator) dan kelas generator Pabrik yang sesuai ( Magento\Framework\ObjectManager\Code\Generator\Factory) digunakan untuk menghasilkan pabrik yang hilang
  3. Semua kelas autogenerasi selalu didasarkan pada kelas lain, dalam kasus pabrik, nama kelas sumber dihitung hanya dengan menghapus Factoryakhiran, itu akan menjadi Magento\Quote\Api\Data\CartItemExtension. Kelas ini tidak ada dan autogenerasi dipanggil sekali lagi oleh autoloader, tetapi kali ini untuk kelas Ekstensi
  4. Sekarang suffix adalah Extensiondan \Magento\Framework\Api\Code\Generator\ExtensionAttributesGeneratorakan digunakan untuk menghasilkan kelas ini
  5. Kelas sumber untuk generasi kelas ekstensi dihitung sebagai Magento\Quote\Api\Data\CartItemInterface, ada dan kelas ekstensi berhasil dibuat. Namun, pada upaya untuk memasukkan file kelas ekstensi, autogeneration dipicu sekali lagi karena Magento\Quote\Api\Data\CartItemExtensionmengimplementasikan Magento\Quote\Api\Data\CartItemExtensionInterface, yang tidak ada
  6. Suffix adalah ExtensionInterfacedan \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGeneratorakan digunakan untuk generasi
  7. ExtensionInterface dan Extension class dihasilkan berdasarkan informasi dari extension_attributes.xml, dapat diakses melalui \Magento\Framework\Api\ExtensionAttribute\Config, kemudian Factory dihasilkan

Satu catatan penting adalah bahwa tidak ada preferensi untuk ExtensionInterface di di.xmlkarena Extension dan ExtensionInterface keduanya dibuat otomatis. Ini bukan masalah karena ExtentionInterface tidak diharapkan disuntikkan secara langsung.

Alex Paliarush
sumber
@ Vinai sama-sama Bounty adalah kejutan yang menyenangkan, terima kasih. Perbarui: hanya FYI, jika hadiah dimulai setelah jawaban diterima, itu tidak diberikan secara otomatis.
Alex Paliarush
0

Bagi saya, malam ini, di atas jawaban dari @Alex, saya bisa melihat kalimatnya

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

di dalam kelas \Magento\Framework\Api\ExtensionAttributesFactory

adalah tempat di mana kita mungkin ingin memulai debug jika antarmuka ekstensi tidak dihasilkan. Atribut ekstensi cukup banyak adalah tentang penataan kelas kami seperti yang diharapkan Magento 2.

baris ini mengatakan:

  • adalah kelas di extension_attributes kami sebuah antarmuka

  • apakah itu meluas \ Magento \ Framework \ Api \ ExtensibleDataInterface

  • memiliki antarmuka ini fungsi yang disebut getExtensionAttributes

Herve Tribouilloy
sumber