Overview of code generation
The Magento application generates code to create non-existent classes. As an example, look at the \Magento\Customer\Model\Resource\AddressRepository constructor. A snippet follows:
...
public function __construct(
\Magento\Customer\Model\AddressFactory $addressFactory,
...
The first constructor parameter has a type of Magento\Customer\Model\AddressFactory
. However, this class does not exist in \Magento\Customer\Model
in the Magento 2 codebase. The Magento application generates this class because its name uses a recognized convention (in this case, because the name ends with Factory
).
Unlike some other languages or libraries, you can look at the generated code on the file system to see what really happens and still debug the code.
When is code generated?
Provided the Magento application is not set for production mode, code is generated when the Magento application cannot find a class when executing code.
In particular,
-
A Factory class creates instances of a type. For example, a generated
\Magento\Customer\Model\AddressFactory
creates new instances of\Magento\Customer\Model\Address
. The code inAddressFactory
provides 鈥渢ypeSafety鈥 (@return annotation) so IDEs understand the type of returned object for theAddress
type. -
You can designate a Proxy to be generated for a type. A proxy is a wrapper for a base class, and the proxy must implement all functions of the base class to delegate those functions to the class.
A proxy results in better performance because a proxy can be instantiated without instantiating its base class. The base class is instantiated only if one of its methods gets called. Therefore, if a class is used as a dependency, but takes a long time to instantiate and the class methods are used only during some paths of execution, using the proxy instead saves time.
As a practical example, you can see the StoreManager class and then see the generated StoreManager Proxy class.
You can also use the code compiler to generate code at any time. In Magento 2, 鈥渃ompiling鈥 your application means performing code generation for any eligible class encountered by the configuration/code scanner, as well as performing a number of different dependency injection optimizations.
Why should you regenerate code?
Suppose a Customer or Proxy class for a Customer class is generated and the Customer class has new methods added to it. Because a Customer or Proxy exists on the file system, it is not regenerated. However, the Customer or Proxy implementation is incomplete now because it does not have the new methods. In this case, you must regenerate the Customer or Proxy class.
If the code generator implementation itself is changed, you must regenerate all the classes. This is rare, however.
Advantages of generating code
Code generation is required in Magento 2. Generating code assures you of the following:
- The code is correct. You don鈥檛 have to worry that the generated code is delegating to the wrong method or forgetting a semicolon, and you don鈥檛 have to write tests for the generated code.
- Code generation writes the boilerplate code to enable you to write more challenging and interesting code.
-
Consistent implementation.
All generated Factories work the same way. After you learn know how one Factory works, you know how they all work.
Object Manager responsibility for code compilation
When code changes as discussed in the preceding section, one of two Object Manager classes compiles it. The class is chosen based on whether or not the single-tenant compiler or the multi-tenant compiler has been run before.
The single-tenant and multi-tenant compiler create var/di/global.ser
, which is a PHP serialized map of all constructor definitions mixed with object linking configuration defined in di.xml. di.xml
is the dependency injection configuration. There is a global app/etc/di.xml
and there can one defined for every module.
If you’re preparing to deploy to production, you must use the multi-tenant compiler. There is a known issue with the single-tenant compiler that prevents it from compiling proxies.
Depending on whether or not one of the compilers has been run before, the Magento application consumes the compilation using one of the following classes:
-
Magento\Framework\Interception\ObjectManager\Config\Compiled, which is used if
global.ser
exists. -
Magento\Framework\Interception\ObjectManager\Config\Developer, which is used if
global.ser
does not exist.This class is slower than
Magento\Framework\Interception\ObjectManager\Config\Compiled
.
The Developer
class has nothing to do with Magento's developer mode.
Find us on