Magento2 Configuration – Merging di.xml with Arguments

configurationdimagento2router

I've been working through Magento U's Fundamentals of Magento 2 Development course, and I'm currently working on the second unit, which covers request processing. This morning, I was finishing the videos and exercises on routers in Magento 2. One of the exercises that was provided involved writing a custom router.

I added the router to the routerlist with the following code in etc/di.xml:

<type name="Magento\Framework\App\RouterList">
    <arguments>
        <argument name="routerList" xsi:type="array">
            <item name="training" xsi:type="array">
                <item name="class" xsi:type="string">Module\Router\Name</item>
                <item name="disable" xsi:type="boolean">false</item>
                <item name="sortOrder" xsi:type="string">70</item>
            </item>
        </argument>
    </arguments>
</type>

I was surprised, when I ran the application, to find that the router wasn't working as expected. I stepped into the code with Xdebug and realized that Magento 2 wasn't even loading the router into the RouterList. After doing a bit of Googling, I realized that I had put the type in etc/di.xml, while others were putting the type declaration in etc/frontend/di.xml. I didn't think this would make a difference, but I moved my file into the frontend area, and to my chagrin, it worked.

I was under the impression that Magento 2 merged the DI files together, including the global and the applicable area-specific files; however, if I were correct, my first attempt would have worked.

So, how does Magento 2 handle merging the global and area-specific di.xml files together, specifically when processing types, and why didn't declaring the code in the etc/di.xml work, when etc/frontend/di.xml did?

Best Answer

See the question/answer Marius linked to: https://magento.stackexchange.com/a/139912/1905

The simple answer is that DI of the same scope gets merged together. DI of a higher scope overwrites a lower scope.

That means values set in etc/frontend/di.xml will be combined with other values set in etc/frontend/di.xml files, but will overwrite values set in etc/di.xml files (when you're in a frontend area). In your example, the core router list is defined in frontend, so that's why your addition didn't take effect when you had it in the global scope.

Related Topic