Magento 2 – What Triggers the Generation of a Factory

compilerdependency-injectionfactorymagento2

Magento 2 contains a number of class files that are either pre-generated, or are generated on the fly. They live in

var/generated

These generated files include factory classes. From the documentation, it's my understanding that a programmer uses factory classes to instantiate "non-injectable" objects. A "non-injectable" object is an object that can't be added via __constructor dependency injection, usually because it requires user input to instantiate.

What's not clear from the documentation is how Magento 2 knows it needs to generate a factory class. This bit

If a non-existent factory is encountered by object manager in runtime mode or compiler, the object manager generates the factory.

makes it sound like if I use a factory class in the object manager (or, by extension, in the dependency injection __constructors), that Magento 2 will generate it for me. But how does the object manager know the thing I'm requesting is a factory?

Also, there seems to be two commands for automatically generating (or "compiling") all the generated classes. Running either of these commands generates a large number of Factory classes. What configuration and/or code files are these commands looking at to generate the needed factory objects?

I know that tracing the object manager and/or command code all the way down would reveal this, but I'm hoping to avoid that long and arduous journey.

Best Answer

Some interesting code location for how this all works together: https://github.com/magento/magento2/blob/develop/dev/tests/integration/testsuite/Magento/Framework/Code/GeneratorTest.php#L40

With the different types coming mostly from here https://github.com/magento/magento2/tree/develop/lib/internal/Magento/Framework/ObjectManager/Code/Generator but also from here https://github.com/magento/magento2/tree/develop/lib/internal/Magento/Framework/Interception/Code/Generator for the Interception code.

It is all triggered by the autoloader here 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;
}
Related Topic