Question

I read about the Parameter configuration inheritance in Magento documentation but not able to understand the concept properly!

https://devdocs.magento.com/guides/v2.4/extension-dev-guide/build/di-xml-file.html#parameter-configuration-inheritance

Can anyone please guide and provide a detailed explanation with an example?

Many many thanks!

Was it helpful?

Solution

I have worked on an example for this inheritance issue you are interested in.

If you look at this class \Magento\Framework\View\Element\Template, you will see one of its parameter is $_logger and although this parameter is a convenient way to log message when debugging and so on, it is common to find your log file contains so many messages that it makes your task to debug more complicated than you'd want.

With that in mind, I have created a new Block class called \Mbs\BlockWithCustomLogger\Block\ARandomBlock and within this class, I have added a dependency like below

    class ARandomBlock extends \Magento\Framework\View\Element\Template
        implements \Mbs\BlockWithCustomLogger\BlockWithCustomLoggerInterface
    {
        private $customLogger;
    
        public function __construct(
            Template\Context $context,
            \Mbs\BlockWithCustomLogger\CustomLoggerInterface $customLogger,
            array $data = []
        ) {
            parent::__construct($context, $data);
            $this->customLogger = $customLogger;
        }

...

then in my di.xml I have defined what is the class to use for customLogger.

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Mbs\BlockWithCustomLogger\Block\ARandomBlock">
        <arguments>
            <argument name="customLogger" xsi:type="object">Mbs\BlockWithCustomLogger\LoggerGeneric</argument>
        </arguments>
    </type>
..

finally, the logger class is \Mbs\BlockWithCustomLogger\LoggerGeneric and this file will log its debug message on a custom file

 class LoggerGeneric implements \Mbs\BlockWithCustomLogger\CustomLoggerInterface
    {
        private static $defaultLogFile = 'blockgeneric.log';
    
        protected $logFile = null;
..

At this point, we have now a way for our custom code to log its debug info on a file that is different than system.xml.

I assume you have seen the above is a use of the devdocs step1 you have read and would like info about.

Then, to illustrate step 2, I have also created another Block class

 class BlockWithLogging1 extends \Mbs\BlockWithCustomLogger\Block\ARandomBlock
        implements \Mbs\BlockWithCustomLogger\BlockWithCustomLoggerInterface
    {
    
    }
        ..

If I was using my class doing nothing else in my di.xml file, for this second block, its debug message would go to the same file blockgeneric.log.

However, if I add a definition in my di.xml like

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Mbs\BlockWithCustomLogger\Block\ARandomBlock">
        <arguments>
            <argument name="customLogger" xsi:type="object">Mbs\BlockWithCustomLogger\LoggerGeneric</argument>
        </arguments>
    </type>
    <type name="Mbs\BlockWithCustomLogger\Block\BlockWithLogging1">
        <arguments>
            <argument name="customLogger" xsi:type="object">Mbs\BlockWithCustomLogger\LoggerType1</argument>
        </arguments>
    </type>
</config>

and the log class like below

class LoggerType1 extends \Mbs\BlockWithCustomLogger\LoggerGeneric
{
    protected $logFile = 'blocktype1.log';
}

then this new block will use another logger class.

This illustrates the same concept as the devdocs article. I have a full module at https://bitbucket.org/magstaging/blockwithcustomlogger/src/master/ that you can try and experiment to verify the above works in your head too.

Great question, thanks

OTHER TIPS

As per this example

https://devdocs.magento.com/guides/v2.4/extension-dev-guide/build/di-xml-file.html#parameter-configuration-inheritance

<type name="Magento\Framework\View\Element\Context">
        <arguments>
            <argument name="urlBuilder" xsi:type="object">Magento\Core\Model\Url</argument>
        </arguments>
    </type>

This above configuration means That the class 'Magento\Framework\View\Element\Context' configures all instances of Magento\Framework\View\Element\Context which set in their contractor and also from here pass in 'Magento\Core\Model\Url' instance as $urlBuilder in their constructors.

<type name="Magento\Backend\Block\Context">
        <arguments>
            <argument name="urlBuilder" xsi:type="object">Magento\Backend\Model\Url</argument>
        </arguments>
    </type>

This above means:

already magento extend 'Magento\Backend\Block\Context' class from 'Magento\Framework\View\Element\Context'

  1. As per the first configuration we pass the instance of 'Magento\Core\Model\Url' as variable $urlBuilder in 'Magento\Framework\View\Element\Context'.
  2. Now we change the instance 'Magento\Backend\Model\Url' as per the variable $urlBuilder in class 'Magento\Backend\Block\Context' which overwrite from 'Magento\Framework\View\Element\Context'.
  3. So for class 'Magento\Backend\Block\Context' $urlBuilder variable carring instace of 'Magento\Backend\Block\Context' instead of 'Magento\Core\Model\Url'.

I found another answer in the below post with an explanation and example by @Ryan.

https://magento.stackexchange.com/a/256620

More: Configured for a class type parameters are configured for all of their descendants automatically. And descendants are able to override parameters configured for the supertype.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top