Apa yang Memicu Generasi Pabrik di Magento 2

39

Magento 2 berisi sejumlah file kelas yang sudah dibuat sebelumnya, atau dibuat dengan cepat. Mereka tinggal di

var/generated

File-file yang dihasilkan ini termasuk kelas pabrik. Dari dokumentasi , saya memahami bahwa seorang programmer menggunakan kelas pabrik untuk instantiate objek "non-injeksi". Objek "non-injeksi" adalah objek yang tidak dapat ditambahkan melalui __constructorinjeksi dependensi, biasanya karena membutuhkan input pengguna untuk instantiate.

Apa yang tidak jelas dari dokumentasi adalah bagaimana Magento 2 tahu bahwa itu perlu untuk menghasilkan kelas pabrik. Ini sedikit

Jika pabrik yang tidak ada ditemui oleh manajer objek dalam mode runtime atau kompiler, manajer objek menghasilkan pabrik.

membuatnya terdengar seperti jika saya menggunakan kelas pabrik di manajer objek (atau, dengan ekstensi, dalam injeksi dependensi __constructors), bahwa Magento 2 akan menghasilkannya untuk saya. Tetapi bagaimana manajer objek tahu bahwa hal yang saya minta adalah pabrik?

Juga, tampaknya ada dua perintah untuk secara otomatis menghasilkan (atau "mengkompilasi") semua kelas yang dihasilkan. Menjalankan salah satu dari perintah ini menghasilkan sejumlah besar kelas Factory. Apa konfigurasi dan / atau file kode yang dilihat oleh perintah-perintah ini untuk menghasilkan objek pabrik yang dibutuhkan?

Saya tahu bahwa melacak manajer objek dan / atau kode perintah sepanjang jalan akan mengungkapkan ini, tapi saya berharap untuk menghindari perjalanan yang panjang dan sulit itu.

Alan Storm
sumber

Jawaban:

21

Beberapa lokasi kode yang menarik untuk bagaimana semua ini bekerja bersama: https://github.com/magento/magento2/blob/develop/dev/tests/integration/testsuite/Magento/Framework/Code/GeneratorTest.php#L40

Dengan jenis yang berbeda kebanyakan berasal dari sini https://github.com/magento/magento2/tree/develop/lib/internal/Magento/Framework/ObjectManager/Code/Generator tetapi juga dari sini https://github.com/magento / magento2 / tree / develop / lib / internal / Magento / Framework / Interception / Code / Generator untuk kode Interception.

Semuanya dipicu oleh autoloader di sini https://github.com/magento/magento2/blob/develop/lib/internal/Magento/Framework/Code/Generator/Autoloader.php#L32

public function load($className)
{
    if (!class_exists($className)) {
        return Generator::GENERATION_ERROR != $this->_generator->generateClass($className);
    }
    return true;
}
Kristof di Fooman
sumber
9

Saya belum menemukan dalam kode, kondisi di mana pabrik dihasilkan, tetapi dari pemahaman saya kelas pabrik dihasilkan ketika diminta dan tidak ditemukan.
Ada beberapa kata kunci yang dipesan Factory, Proxy, Interceptor, jika digunakan, akan memicu pembuatan kode ketika kelas-kelas tertentu tidak ditemukan.
Saya akan memposting kembali segera setelah saya menemukan kode yang memicu generasi pabrik.
Jadi, jika Anda meminta kelas Some\Namespace\HereFactorydan kelas tidak ada, karena diakhiri dengan kata kunci Factoryitu akan dihasilkan dalamvar/generation/Some/Namespace/HereFactory.php

Marius
sumber
Sepertinya dokumen harus diperbarui karena ObjectManager tidak benar-benar menghasilkan. Pemuat otomatis khusus adalah bagian dari jawabannya. github.com/magento/magento2/blob/develop/lib/internal/Magento/…
Chris O'Toole
1
Itu sejalan dengan pengalaman saya (lihat gist.github.com/astorm/f245ce9c761c9a8053aa), tetapi itu menimbulkan pertanyaan 1. Di mana hal ini terjadi dalam kode manajer objek (yaitu apa konvensi sebenarnya) 2. Bagaimana kompiler / generator tahu pabrik apa yang akan dihasilkan?
Alan Storm
8

Saya menggali sup kacang yang sama ini sekarang. Pemahaman saya sejauh ini adalah bahwa semua hal yang dihasilkan secara otomatis /var/generationdilakukan dari preferensi dan antarmuka yang dinyatakan dalam app/etc/di.xml.

Antarmuka dan preferensi Anda akan dinyatakan dalam di.xmlfile di /app/code/Vendor/<module>/etc/di.xml.

Ia tahu untuk menghasilkan objek untuk Anda karena Anda telah mendeklarasikan antarmuka di __constructorAND Anda dan telah menyatakan preferensi untuk antarmuka itu baik secara global maupun lokal dalam di.xmlfile yang sesuai .

Saya menawarkan tiga butir garam dengan komentar saya.

Dave G
sumber
Memberi +1 untuk informasi bermanfaat - tetapi sepertinya Pabrik berasal dari suatu tempat selain di.xmlfile - Anda dapat mengirim sesuatu ke manajer objek yang berakhir di Pabrik dan itu akan menghasilkan file untuk Anda.
Alan Storm
Apakah ini membantu? bit.ly/1BOtdie
Steve Johnson