Widgets, same as in Yii 2 are created by inheriting from Widget class. Since it has events, it needs event dispatcher in order to raise them. We have two ways of passing it right now.
First, making event manager requirement explicit via constructor. Then child class would look like:
class MyWidget extends Widget
{
private MyDependency $myDependency;
public function __construct(MyDependency $myDependency, EventDispatcherInterface $eventDispatcher)
{
$this->myDependency = $myDependency;
parent::__construct($eventDispatcher);
}
}
Another way is to pass event manager via setter. Then the constructor becomes cleaner:
class MyWidget extends Widget
{
private MyDependency $myDependency;
public function __construct(MyDependency $myDependency)
{
$this->myDependency = $myDependency;
}
}
But in case dispatcher isn’t passed via setDispatcher(), not events will be triggered at all.
class MyWidget extends Widget
{
private MyDependency $myDependency;
public function __construct(MyDependency $myDependency, EventDispatcherInterface $eventDispatcher)
{
$this->myDependency = $myDependency;
parent::__construct($eventDispatcher);
}
}
I particularly prefer the explicit requirement so when I see the class automatically I see what its dependencies are, and I know that I must inject it into the constructor, it is also more readable and easier to test.
With clean constructor we can also make the EventDispatcherInterface dependency to required.
The widget is created through the factory, so required dependencies can easily be passed through setters.
It makes perfect sense, for example for testing - it is easier to create instance specifying dependencies explicitly instead of relying on some factory magic. You can’t assume that every instance will be created using factory.
I don’t want to test factory. I want to test widget.
There is a difference in API, testing is only an example. If EventDispatcherInterface is required dependency, then it should be clear that it is required. Constructor parameters is clean and common way to specify this requirements. Using setter and hiding it behind optional helper method is another tricky thing the user needs to learn (especially if we ignore missing EventDispatcherInterface dependency and do not handle events at all in this case).