I am using this config in di.xml
<virtualType name="ourFirstVirtualType" type="Test\Testmod\Model\Newmodelclass">
<arguments>
<argument name="test_object" xsi:type="object">Test\Testmod\Model\Example2</argument>
</arguments>
</virtualType>
<type name="Test\Testmod\Model\Modelclass">
<arguments>
<argument name="the_object" xsi:type="object">ourFirstVirtualType</argument>
</arguments>
</type>
This is the Modelclass
<?php
namespace Test\Testmod\Model;
class Modelclass
{
public $testProperty;
public function __construct(Newmodelclass $the_object)
{
$this->testProperty = $the_object;
}
}
and this is Newmodelclass
<?php
namespace Test\Testmod\Model;
class Newmodelclass
{
public $newTestProperty;
public function __construct(Againnewmodelclass $test_object)
{
$this->newTestProperty = $test_object;
}
}
Now I am trying to test virtual type with this controller
<?php
namespace Test\Testmod\Controller\Index;
use Test\Testmod\Model\Modelclass;
use Test\Testmod\Model\Newmodelclass;
use Test\Testmod\Model\Againnewmodelclass;
class Index extends \Magento\Framework\App\Action\Action
{
public function __construct(
\Magento\Framework\App\Action\Context $context,
Modelclass $Modelclass,
Newmodelclass $Newmodelclass,
Againnewmodelclass $Againnewmodelclass
) {
parent::__construct($context);
$this->Modelclass = $Modelclass;
$this->Newmodelclass = $Newmodelclass;
$this->Againnewmodelclass = $Againnewmodelclass;
}
public function execute()
{
echo "<pre>";
var_dump($this->Modelclass);
var_dump($this->Newmodelclass);
var_dump($this->Againnewmodelclass);
die;
}
}
I think this should work correct right but giving this error instead
PHP Fatal error: Uncaught TypeError: Argument 1 passed to Test\Testmod\Model\Newmodelclass::__construct() must be an instance of Test\Testmod\Model\Againnewmodelclass,
instance of Test\Testmod\Model\Example2 given, called in /var/www/html/magento226/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 111
and defined in /var/www/html/magento226/app/code/Test/Testmod/Model/Newmodelclass.php:7
Best Answer
Let's break down the dependency chain going from controller.
First argument is
\Magento\Framework\App\Action\Context $context
which is core object and will work as expected provided nothing has been altered.The next argument that the DI will want to inject is
Modelclass $Modelclass
, which resolves toTest\Testmod\Model\Modelclass
as defined inuse
statement. Now the DI will try to instantiate an object of this class. It will look at its constructor and will see there is 1 argument defined there, namelyNewmodelclass $the_object
. In regular situation where there is no additional configuration indi.xml
this class would be resolved toTest\Testmod\Model\Newmodelclass
by using the same namespace as there is nouse
statement.However you have prepared a config in
di.xml
stating thatthe_object
argument will be resolved toourFirstVirtualType
. So in this case DI will try to instantiate that and will resolve this name toTest\Testmod\Model\Newmodelclass
as defined indi.xml
. So far so good. We have correctly found the class to inject intoTest\Testmod\Model\Modelclass
.Now DI will proceed to instantiating
Test\Testmod\Model\Newmodelclass
and it will read constructor argument of$test_object
being locked atAgainnewmodelclass
(which by namespace isTest\Testmod\Model\Againnewmodelclass
). However indi.xml
you've defined that when instantiating virtual type ofourFirstVirtualType
you want to pass astest_object
argument classTest\Testmod\Model\Example2
. This will then be used and the DI constructor will create an instance ofTest\Testmod\Model\Example2
and inject it toTest\Testmod\Model\Newmodelclass
.But here is a problem. To make it work
Test\Testmod\Model\Example2
must be ofTest\Testmod\Model\Againnewmodelclass
type or a descendant of it and in your case it seems it isn't. Either makeTest\Testmod\Model\Example2
a child ofTest\Testmod\Model\Againnewmodelclass
or change the constructor definition inTest\Testmod\Model\Newmodelclass
to use an interface or a class type that will work with usingTest\Testmod\Model\Example2
as an argument.