7

I'm having some trouble with virtual types. I've done some research and this is what I have.

0: A class which takes a string argument

1: A virtual type based on above class with a constant value for above argument.

2: A concrete class in which I'm injecting above virtual type.

Now, from what I understand I imagine that an object should be injected. instead I get an array. Any help would be highly appreciated. I'm sharing the code as well.

The class that sits at the base of the virtual type

namespace Company\Extension\Model\Product\Attribute\Source;

class Test
{
    /**
     * @var
     */
    protected $string;

    public function __construct($test)
    {
        $this->string = $test;
    }

    public function test()
    {
        return $this->string;
    }
}

The 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">

    <virtualType name="VirtualTypeName" type="\Company\Extension\Model\Product\Attribute\Source\Test">
        <arguments>
            <argument name="test" xsi:type="string">foo</argument>
        </arguments>
    </virtualType>

    <type name="Company\Extension\Controller\Test\Test">
        <arguments>
            <argument name="context" xsi:type="object">Magento\Framework\App\Action\Context</argument>
            <argument name="test" xsi:type="object">VirtualTypeName</argument>
        </arguments>
    </type>
</config>

The class in which I'm injecting the virtual type:

class Test extends \Magento\Framework\App\Action\Action
{
    protected $test;

    public function __construct(
        Context $context,
        $test
    )
    {
        $this->test = $test;
        parent::__construct($context);
    }

    public function execute()
    {
        ini_set('xdebug.var_display_max_depth', 5);
        ini_set('xdebug.var_display_max_children', 256);
        ini_set('xdebug.var_display_max_data', 1024);

        var_dump($this->test);
        exit;
    }
}

The result of the var_dump:

array (size=1)
  'instance' => string 'VirtualTypeName' (length=15)

2 Answers 2

7

I needed to strong type the argument.

class Test extends \Magento\Framework\App\Action\Action
{
    protected $test;

    public function __construct(
        Context $context,
        \Company\Extension\Model\Product\Attribute\Source\Test $test //changes on this line
    )
    {
        $this->test = $test;
        parent::__construct($context);
    }

    public function execute()
    {
        ini_set('xdebug.var_display_max_depth', 5);
        ini_set('xdebug.var_display_max_children', 256);
        ini_set('xdebug.var_display_max_data', 1024);

        var_dump($this->test);
        exit;
    }
}
0

This is the tip for all of the people googling this question like me.

You need to strong type the argument (provide class or interface), and the object you are passing has to inherit or implement this type.

Keep in mind, that is also the cause, that you are unable to pass factory generated in Magento as an argument for virtualType. That's because One object can be instance of Another object, but factory of object One is not an instance of the factory of Another object.

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.