Magento – Circular dependency: Magento\Customer\Model\Session depends on Company\Modulename\Plugin\Config\Share and vice versa

magento2overridesplugin

How to override or Use plugin for isWebsiteScope() function from
Magento\Customer\Model\Config\Share.php file,

I have used plugin for below function but I want to get current customer session in below function, Mainly check custoemr is logged in or not.

Just use plugin and set di.xml,

<!-- Override Share.php to set value of website scope -->
<type name="Magento\Customer\Model\Config\Share">
    <plugin name="Company_Modulename::Share" type="\Company\Modulename\Plugin\Config\Share\Proxy" sortOrder="1"/>
</type>

In Share.php file,

<?php
namespace Company\Modulename\Plugin\Config;

class Share
{    
    public function __construct(
        \Magento\Customer\Model\Session $customerSession
    ) {
        $this->session = $customerSession;
    }
    /**
     * Check whether current customers sharing scope is website
     *
     * @return bool
     */
    public function afterIsWebsiteScope(\Magento\Customer\Model\Config\Share $subject)
    {
        if(!$this->session->isLoggedIn()){
            return 1;
        } else {
            return 0;
        }

    }
}

How to get current customer session in above function,

If I used current customer session using customer session model browser will throw Circular dependacy error.

Best Answer

The easiest way to resolve circular dependencies (though not always the best) is to use Proxies.

Proxy for a class is an auto-generated class (meaning, Magento will create it automatically if not found through auto-loader) which has a dependency on the Object Manager and has the same interface as the original class.

Implementation of any method of the Proxy is just an invocation of the same method of the original class. It does not have original class required in constructor, instead the object of the original class is created through the Object Manager the first time some method of the Proxy is invoked.

Here is an example of the Proxy from the core (\Magento\Backend\Model\Auth\Proxy):

/**
 * Get proxied instance
 *
 * @return \Magento\Backend\Model\Auth
 */
protected function _getSubject()
{
    if (!$this->_subject) {
        $this->_subject = true === $this->_isShared
            ? $this->_objectManager->get($this->_instanceName)
            : $this->_objectManager->create($this->_instanceName);
    }
    return $this->_subject;
}

/**
 * {@inheritdoc}
 */
public function setAuthStorage($storage)
{
    return $this->_getSubject()->setAuthStorage($storage);
}

To use a proxy, instead of reference to the class (anywhere in di.xml or in constructor dependency), reference the Proxy by appending the name of the class with \Proxy, i.e.:

<type name="Magento\Customer\Model\Config\Share">
<plugin name="Company_Modulename::Share" type="\Company\Modulename\Plugin\Config\Share\Proxy" sortOrder="1"/>

It is always worthwhile analyzing are there ways to rewrite the business logic to avoid circular dependencies before using Proxies (or for the same matter an Object Manager in constructor)