The process of creating objects in Magento 2 includes some features inherent in Magento 2 and associated with automatic code generation under certain conditions ( proxies , factories and interceptors ). With interceptors, everything was more or less clear for me, but the purpose of the two other types of generated classes was hidden by a fog of misunderstanding. And if I still have fog for the factories, then for the proxy classes, the fog has cleared.
Suppose we make a command to perform some action in CLI mode. Suppose that in this command we use the implementation of the \Magento\Quote\Api\CartManagementInterface
, which is passed to the ObjectManager constructor:
public function __construct(\Magento\Quote\Api\CartManagementInterface $cartManagement) {}
We can not use the \Magento\Quote\Api\CartManagementInterface
directly in our team, this implementation can be pulled indirectly - our team depends on \ClassA
, which depends on \ClassB
, which depends on ..., which depends on \Magento\Quote\Api\CartManagementInterface
.
However, if our team has a direct or indirect dependence on the default implementation of the \Magento\Quote\Api\CartManagementInterface
, then when trying to run a command, for example:
$ ./bin/magento list
we fall out by mistake
[Magento\Framework\Exception\SessionException] Area code not set: Area code must be set before starting a session.
This is because before starting ./bin/magento
creates all the commands that are specified in the etc/di.xml
descriptors. To create our team, ObjectManager creates a class \Magento\Quote\Model\QuoteManagement
, implementing the \Magento\Quote\Api\CartManagementInterface
. In the process of creating dependencies for this class, ObjectManager reaches the creation of dependencies \Magento\Framework\Session\SessionManager
in the constructor of which there is a line:
$this->start();
and if for some reason (for example, Area code not set ) the session does not start, an exception is thrown and the execution of the CLI command abnormally terminates. And it doesn’t matter that we didn’t intend to use the sessions while executing our team (or didn’t suspect that creating something there that implements the interface we need will fly out because it’s necessary to create this “something there” resource that is not projected in this mode).
The developers of Magento 2, faced with such non-kosher behavior of objects in the process of their creation by ObjectManager, came to a simple solution - proxy classes. It is enough to specify in the constructor a dependency not on \Magento\Quote\Api\CartManagementInterface
, but on \Magento\Quote\Api\CartManagementInterface\Proxy
, and when you create your object, the interface decorator will not be transferred to it (automatically generated ), which will create direct implementation at the first use of any method being implemented.
In other words, it is enough to add after the name of the interface or class \Proxy
:
public function __construct(\Magento\Quote\Api\CartManagementInterface\Proxy $cartManagement) {}
how the problem with the launch of the command is solved (if it does not solve it, clean the rendered: rm -fr ./var/cache/* ./var/generation/*
). \ClassA\Proxy
, ClassB\Proxy
, ..., \Magento\Quote\Api\CartManagementInterface\Proxy
- choose the level you like.
Alan Storm has a good article " Magento 2 Object Manager: Proxy Objects " (he has a lot of good articles on Magento 2), but it wasn’t quite clear to me exactly why Proxy Decorators were created in Magento 2 and what is the scope their application. Only after I was faced with the inability to translate my application in production mode
$ ./bin/magento deploy:mode:set production
Due to the treacherous behavior of some designers, I have somewhat clarified for myself the scope of the use of proxy classes in Magento 2.
Source: https://habr.com/ru/post/317162/
All Articles