Magento 2 di.xml Parameter configuration inheritance explanation with example
-
14-04-2021 - |
Domanda
I read about the Parameter configuration inheritance
in Magento documentation but not able to understand the concept properly!
Can anyone please guide and provide a detailed explanation with an example?
Many many thanks!
Soluzione
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
Altri suggerimenti
As per this example
<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'
- As per the first configuration we pass the instance of 'Magento\Core\Model\Url' as variable $urlBuilder in 'Magento\Framework\View\Element\Context'.
- 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'.
- 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.
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.