2

I'm under the impression that we can inject data into classes using di.xml and the $data array dependency. I'm struggling with getting it working however. Am I not understanding the concept correctly? Or am I missing some configuration?

Below is my (simplified) code.

etc/frontend/di.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="DannyNimmo\Subcategories\Block\ListCategory">
        <arguments>
            <argument xsi:type="array" name="data">
                <item xsi:type="string" name="test">test</item>
            </argument>
        </arguments>
    </type>
</config>

Block/ListCategory.php:

<?php

namespace DannyNimmo\Subcategories\Block;

class ListCategory
    extends \Magento\Framework\View\Element\Template
    implements \Magento\Framework\DataObject\IdentityInterface
{

    public function __construct (
        \Magento\Framework\View\Element\Template\Context $context,
        array $data = []
    ) {
        parent::__construct($context, $data);
        var_dump($data);
    }

}

Edit: I should say that I am seeing an empty array array(0) { } as the output.

3
  • Have you tried re-running magento setup:di:compile or deleting the contents of the var/di and var/generation folders? Feb 12, 2017 at 7:46
  • @AndrewNoble Yeah, I'm running in developer mode, and have cleared those directories multiple times. Feb 12, 2017 at 7:58
  • @DannyNimmo have you got the answer yet? Feb 8, 2019 at 16:57

1 Answer 1

0

I can't test your code at the moment to solve your issue but I'd like to add something that can be useful.

DI is intended to pass injectables, that are classes that encapsulate some logic. DI shouldn't be used to pass data, the so called newables.

For example, if you need the data you are trying to inject, you should instead inject a class that is responsible of retrieving that data. This kind of classes are called repositories. In some circumstances it's better to use factories.

You can read more here.

Enjoy.

10
  • Are you sure? For example: there are multiple session managers. Each instance use custom session namespace ( like in Magento). Are you think, that we need to hardcode all namespaces in services ( SessionNamespaceProvider for example ) instead of setup namespaces values via di.xml?
    – Max
    Feb 12, 2017 at 10:28
  • In this case I was wanting to inject via DI for customisability, i.e. data can be easily added by another module. What is your opinion on the purpose of $data in this case? Feb 12, 2017 at 11:06
  • @danny you can also set data values using layout configuration (attributes tag in block declaration)
    – Max
    Feb 12, 2017 at 13:50
  • Sorry @Max I don't understand your point. The di.xml is the "default" mapping between an interface declaration (the one you pass to the constructor) and the actual class you want to instantiate. It's ok to use di.xml to change that mapping for session managers that are a perfect example of injectables. Feb 13, 2017 at 7:00
  • Hi @DannyNimmo I don't like the idea of passing data via di.xml; so said feel free to use the framework the way you prefer. Feb 13, 2017 at 7:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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