Closed kirkmadera closed 4 months ago
If I have followed your explanation correctly, then an alias should help: https://docs.laminas.dev/laminas-servicemanager/v4/configuring-the-service-manager/#aliases
The alias of Mezzio\Swoole\Event\EventDispatcherInterface
to Mezzio\Swoole\Event\EventDispatcherFactory
is already present in Mezzio\Swoole\ConfigProvider
. Which means that I can create a factory class an get Mezzio\Swoole\Event\EventDispatcherInterface
from the container. But I still have to create the factory.
I can avoid creating the factory altogether, if the __constructor directly asks for Mezzio\Swoole\Event\EventDispatcherInterface
instead of Psr\EventDispatcher\EventDispatcherInterface
.
This is sort of a design decision. It mucks up the constructor a bit since Mezzio\Swoole\Event\EventDispatcherInterface
adds no functionality and is just a marker interface. But it's helpful in reducing the boilerplate code of factories.
I noticed this statement in https://mwop.net/blog/2022-01-21-openswoole-timer-cron.html that @weierophinney does alias the PSR-14 interface directly. I am guessing that is why it is like that in the docs.
To allow these "workflow" events to be separate from the application if desired, we register a Mezzio\Swoole\Event\EventDispatcherInterface service that returns a discrete PSR-14 event dispatcher implementation. I generally alias this to the PSR-14 interface, so I can use the same instance for application events.
Another design decision if you want to recommend that or not, but it should be made clear in the docs also. I don't have a strong opinion either way and could be on board with aliasing it entirely since it's really the app's event manager in this case.
It may be an anti-pattern to have an app level event manager. I like the idea of having an event manager tied to specific logic domains. I have avoided a global event manager so far and it has worked for us.
The alias of
Mezzio\Swoole\Event\EventDispatcherInterface
toMezzio\Swoole\Event\EventDispatcherFactory
is already present inMezzio\Swoole\ConfigProvider
.
This not an alias:
Which means that I can create a factory class an get
Mezzio\Swoole\Event\EventDispatcherInterface
from the container. But I still have to create the factory.
Create an alias for Psr\EventDispatcher\EventDispatcherInterface
which maps to Mezzio\Swoole\Event\EventDispatcherInterface
.
Compare with:
But please note, I don't use Swoole, so I can only answer in general or be wrong.
If the recommendation is to override EventDispatcherInterface directly, this is not relevant. Closing
@kirkmadera No, nothing needs to be overwritten, add another alias to your configuration:
return [
'dependencies' => [
'aliases' => [
Psr\EventDispatcher\EventDispatcherInterface => Mezzio\Swoole\Event\EventDispatcherInterface,
],
// …
],
];
Then the ReflectionBasedAbstractFactory
from laminas-servicemanager can resolve the service under the name Psr\EventDispatcher\EventDispatcherInterface
.
See the link from my first comment above: https://docs.laminas.dev/laminas-servicemanager/v4/configuring-the-service-manager/#aliases
Feature Request
Make the
Mezzio\Swoole\Event\EventDispatcherInterface
compatible withLaminas\ServiceManager\AbstractFactory\ReflectionBasedAbstractFactory
or similar concept DI factory.Summary
In the Message Handler example,
Psr\EventDispatcher\EventDispatcherInterface
is used in the constructor. TheMessageHandlerFactory
in the example injects an instance ofPsr\EventDispatcher\EventDispatcherInterface
implying that thePsr\EventDispatcher\EventDispatcherInterface
service name should be overridden in DI for Mezzio Swoole. I don't think that is the intent. The factory in the example should instead get an instance ofMezzio\Swoole\Event\EventDispatcher
from the container.That said, any class using this strategy will require a factory so that the correct instance of
Psr\EventDispatcher\EventDispatcherInterface
can be set. The ReflectionBasedAbstractFactory cannot determine this. If you makeMezzio\Swoole\Event\EventDispatcherInterface
extendPsr\EventDispatcher\EventDispatcherInterface
and makeMezzio\Swoole\Event\EventDispatcher
implementMezzio\Swoole\Event\EventDispatcherInterface
, thenMezzio\Swoole\Event\EventDispatcherInterface
could be used in the constructor and the ReflectionBasedAbstractFactory could not target these correctly without needing to make a factory per class.I use this strategy wherever I can to reduce boilerplate code. It convolutes the constructor slightly by not directly having
Psr\EventDispatcher\EventDispatcherInterface
, but to me, it is worthwhile to allow for reflection based DI strategies to handle this.