1

I kind of understand how the logic and the benefit of proxies in Magento 2 di. But can anybody tell me, how to use it?!

Alan Storm use the generated proxy class, for example, I would call

\Magento\Store\Model\StoreManagerInterface\Proxy in my construct method.

But if I take a look in Magento di.xml files and also in the respective php class, the constructor class does not call a proxy. e.g.

// module-store/etc/di.xml line 49
<type name="Magento\Store\Model\Resolver\Store">
    <arguments>
        <argument name="storeManager" xsi:type="object">Magento\Store\Model\StoreManagerInterface\Proxy</argument>
    </arguments>
</type>

and the model

// module-store/Model/Resolver/Store.php
/**
 * @param \Magento\Store\Model\StoreManagerInterface $storeManager
 */
 public function __construct(\Magento\Store\Model\StoreManagerInterface $storeManager)
 {
     $this->_storeManager = $storeManager;
 }

So does the constructor call the regular Model interface or the proxy with magic that I don't see till now?

3

Proxies are generated code.
Simply reference a class in the form \Original\Class\Name\Proxy, and the class is generated if it does not exist.
Proxies extend other classes to become lazy-loaded versions of them. That is, a real instance of the class a proxy extends is created only after one of the class’s methods is actually called. A proxy implements the same interface as the original class.
References :
- https://devdocs.magento.com/guides/v2.3/extension-dev-guide/proxies.html
- https://webkul.com/blog/magento2-proxy-design-pattern-code-generation/

| improve this answer | |
  • you just copied Muhammad Hasham's tutorial link – Shoaib Munir Jan 24 '19 at 10:40
2

As we know design patterns are meant for solving a redundant problem in the whole project , proxy design pattern also solves a specific problem. Proxies works as surrogate(means to act on behalf of others) , in programming proxies are classes that can be used in place of any other class, and in magento2 proxies are used in place resource hungry classes.

Lets understand the proxy class:

  • the namespace of the proxy class is same as the original class Magento\Catalog\Model\Product\Attribute\Source\Status so that it can be easily replaced with the original object .
  • Proxy class extends the original class \Magento\Catalog\Model\Product\Attribute\Source\Status so that it can use its public methods.
  • Proxy classes implements \Magento\Framework\ObjectManager\NoninterceptableInterface interface, this is a marker interface menas it is blank, it has no methods and no member variables, it for only signaling that this class cannot be intercepted .
  • And the most important its constructor, as we can see it only has one object dependency that ObjectManager class, so this makes sense as there is only one dependency in the class it will load very quickly and will save a lot of resources(space and time), you will not see a parent constructor call too .
  • __sleep, __wakeup and __sleep these are the php magic functions that executes when a class is invoked or destroyed to perform some actions.
  • _getSubject this method will return the original class object whenever it will be asked for, so it will simply work like a lazy loding process an object will be only provided when it will be requested.
  • And all the other functions are parent(original) class public functions that are overriden in the proxy class so that they can be called on proxy class object, inside these functions it is calling the _getSubject to get the parent object and then call the same function .

Please check this tutorial

https://webkul.com/blog/magento2-proxy-design-pattern-code-generation/

I hope this will help

| improve this answer | |
  • 1
    That's an excellent article – Raul Sanchez Jan 24 '19 at 7:07
1

After reading (and I think, understanding) the article https://webkul.com/blog/magento2-proxy-design-pattern-code-generation/ in one of the answers, I see some different scenarios

Using Proxies seem useless in a single method classes (such as a typical class rewrite, plugin, etc... where we customize a concrete functionality), because we inject in constructor only what we need to use in our method, which will be always called if our class is used in application flow

On the other hand, using Proxies seem a powerful technique when writing new custom models. In that context, if I understood correctly the example in https://devdocs.magento.com/guides/v2.3/extension-dev-guide/proxies.html then it seems useful to define as Proxy practically all injected classes in constructor

class SlowLoading
{
    public function __construct()
    {
        // ... Do something resource intensive
    }

    public function getValue()
    {
        return 'SlowLoading value';
    }
}

class FastLoading
{
    protected $slowLoading;

    public function __construct(
        SlowLoading $slowLoading
    ){
        $this->slowLoading = slowLoading;
    }

    public function getFastValue()
    {
        return 'FastLoading value';
    }

    public function getSlowValue()
    {
        return $this->slowLoading->getValue();
    }
}

Assume that class SlowLoading has a non-trivial performance impact when instantiated (perhaps due to a complex database query or a call to a third-party web API). Because of the dependency injection in the constructor of FastLoading, this impact is incurred if FastLoading is instantiated. Note, however, that the SlowLoading instance is used only in the method getSlowValue, meaning that the resource cost is unnecessary if this method is never called on the FastLoading object.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.