In yii2 we were able to create new Object and inject all dependencies via Yii::createObject
and I still not get what the best practice for Yii3 is.
Imagine you have a FormModel
Car
that contains Wheels
and those wheels require certain Screws
.
So you have 3 Classes
Car
-> Wheel
-> Screw
. And you have a post request that looks somehow like
[
'car' => [
'model' => 'x5',
'wheels' => [
[
'position' => 1,
'type' => 'XYZ',
'screws' => [
['type' => 'A'],
['type' => 'A'],
]
],
[
'position' => 2,
'type' => 'XYZ',
'screws' => [
['type' => 'B'],
['type' => 'B'],
]
],
[
'position' => 3,
'type' => 'XYZ',
'screws' => [
['type' => 'C'],
['type' => 'C'],
]
]
]
]
];
In Yii2 I usually did something like this in my Car
class (this is just an example)
public function setWheels($wheels)
{
$this->wheels = [];
foreach ($wheels as $wheel){
if(is_array($wheel)){
$wheel['__class'] = Wheel::class;
$wheel = Yii::createObject($wheel);
}
$this->wheels[] = $wheel;
}
}
So I could load my post request (the array) and create objects of those again. The Wheel
class on the other hand has the same so I was able to resolve all dependencies.
Imagine the constructor of our Screw
looks like this.
public function __construct(ScrewService $screwService)
{
$this->screwService = $screwService;
}
In that case we would either need to pass that ScrewService
all the way down from the Car
, to the Wheel
and then to the Screw
or do some nasty clones
public class Car
{
public function __construct(Wheel $basicWheel)
{
$this->basicWheel = $basicWheel;
}
public function setWheels($wheels)
{
$this->wheels = [];
foreach ($wheels as $wheel){
if(is_array($wheel)){
$newWheel = clone $this->basicWheel;
$newWheel->load($wheel);
$wheel = $newWheel;
}
$this->wheels[] = $newWheel;
}
}
}
So we have one “basic” Model with all resolved dependencies and due to DI and always clone that. It feels rather ugly too.
My question is: what is best practice here in that case?
Could someone please provide a simple example how to deal with deep nested dependencies that were easily resolved via Yii::createObject
in the past?