Что запускает создание фабрики в Magento 2

39

Magento 2 содержит ряд файлов классов, которые либо предварительно сгенерированы, либо создаются на лету. Они живут в

var/generated

Эти сгенерированные файлы включают фабричные классы. Из документации я понимаю, что программист использует фабричные классы для создания экземпляров «неинъекционных» объектов. «Неинъецируемый» объект - это объект, который не может быть добавлен посредством __constructorвнедрения зависимости, обычно потому, что для его создания требуется пользовательский ввод.

Что не ясно из документации, так это то, что Magento 2 знает, что ему нужно создать фабричный класс. Этот бит

Если менеджер объектов в режиме выполнения или компилятор обнаруживает несуществующую фабрику, менеджер объектов генерирует фабрику.

звучит так, будто если я использую фабричный класс в диспетчере объектов (или, как следствие, в внедрении зависимостей __constructors), Magento 2 сгенерирует его для меня. Но как менеджер объектов узнает, что я запрашиваю фабрику?

Кроме того, кажется, есть две команды для автоматической генерации (или «компиляции») всех сгенерированных классов. Выполнение любой из этих команд генерирует большое количество классов Factory. Какие файлы конфигурации и / или кода эти команды рассматривают для создания необходимых заводских объектов?

Я знаю, что отслеживание менеджера объектов и / или кода команды до конца показало бы это, но я надеюсь избежать этого долгого и трудного пути.

Алан Сторм
источник

Ответы:

21

Интересное расположение кода для того, как все это работает вместе: https://github.com/magento/magento2/blob/develop/dev/tests/integration/testsuite/Magento/Framework/Code/GeneratorTest.php#L40

С различными типами, поступающими в основном отсюда https://github.com/magento/magento2/tree/develop/lib/internal/Magento/Framework/ObjectManager/Code/Generator, а также отсюда https://github.com/magento / magento2 / tree /velop / lib / internal / Magento / Framework / Interception / Code / Generator для кода перехвата.

Все это запускается автозагрузчиком здесь 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;
}
Кристоф в Фуман
источник
9

В коде я не нашел условий, для которых создаются фабрики, но, насколько я понимаю, фабричный класс генерируется, когда он запрашивается и не обнаруживается.
Существуют некоторые зарезервированные ключевые слова Factory, Proxy, Interceptor, если они используются, запускает генерацию кода, когда конкретные классы не найдены.
Я отправлю обратно, как только найду код, который запускает фабричное поколение.
Таким образом, если вы запрашиваете класс, Some\Namespace\HereFactoryа класс не существует, так как он заканчивается ключевым словом, Factoryон будет сгенерирован вvar/generation/Some/Namespace/HereFactory.php

Мариус
источник
Похоже, документы должны быть обновлены, поскольку ObjectManager на самом деле не генерирует. Специальный автозагрузчик является частью ответа. github.com/magento/magento2/blob/develop/lib/internal/Magento/…
Крис О'Тул
1
Это согласуется с моим опытом (см. Gist.github.com/astorm/f245ce9c761c9a8053aa), но это поднимает вопрос 1. Где это происходит в коде менеджера объектов (то есть, каково действительное соглашение) 2. Как работает компилятор / генератор знает, какие заводы генерировать?
Алан Шторм
8

Я копаюсь в этом самом гороховом супе прямо сейчас. Насколько я понимаю, пока все, что автоматически генерируется, /var/generationделается из предпочтений и интерфейсов, объявленных в app/etc/di.xml.

Ваши интерфейсы и предпочтения будут объявлены di.xmlв вашем файле /app/code/Vendor/<module>/etc/di.xml.

Он знает, как сгенерировать объект (ы) для вас, потому что вы объявили интерфейс в своем __constructorAND и объявили предпочтение для этого интерфейса глобально или локально в соответствующем di.xmlфайле.

Я предлагаю три зерна соли с моими комментариями.

Дэйв Дж
источник
+1 за полезную информацию - но кажется, что фабрики приходят откуда-то, кроме di.xmlфайлов - вы можете отправить что-то в диспетчер объектов, который заканчивается в Factory, и он сгенерирует файл для вас.
Алан Сторм
Это помогает? bit.ly/1BOtdie
Стив Джонсон