-
-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Usage of SharedEventManager to use events like with laminas-mvc #92
Comments
In fact, we talked about this a few days ago in the laminas slack: TL;DR: Moving So what we can do is to attach all So for the time being, you can create a final class LaminasMvcCliEventManagerDelegatorFactory
{
public function __invoke(ContainerInterface $container, string $requestedName, callable $callback): EventManagerInterface
{
$eventManager = $callback();
assert($eventManager instanceOf EventManagerInterface);
$listeners = $this->extractListenersFromConfig($container);
foreach ($listeners as $listener) {
$container->get($listener)->attach($eventManager);
}
return $eventManager;
}
/** @return list<string> */
private function extractListenersFromConfig(ContainerInterface $container): array {
if (PHP_SAPI !== 'cli') {
return [];
}
$config = $container->get('config');
$applicationConfig = $container->get('ApplicationConfig');
$listeners = [];
if (isset($applicationConfig['listeners'])) {
$listeners = array_merge($listeners, $applicationConfig['listeners']);
}
if (isset($config['listeners'])) {
$listeners = array_merge($listeners, $config['listeners']);
}
return array_values(array_unique($listeners));
}
} An additional entry to your config like this would register the delegator for the return ['service_manager' => ['delegators' => ['EventManager' => [LaminasMvcCliEventManagerDelegatorFactory::class]]]; |
I tried it, but this seemingly creates loop while instantiating.
|
If I comment out some of the listeners it seems to work. But I can't track down why the loop is happening. I added some echo commands along the creation of the first listener that seems to cause the loop. After going through the chain of factories I can see an object being created successfully (including echo in the last line of the constructor of the object), but after that I can see echo commands of the invoke inside LaminasMvcCliEventManagerDelegatorFactory again. So basically I added for debugging this about foreach in invoke in your code: echo 'beginforeachLaminasMvcCliEventManagerDelegatorFactory'; The factory that I public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
echo 'ya';
$c1 = $container->get(ClassThatIsBeingCreatedSuffessfullyInclEchoInConstructor::class); // will echo 'xxx' in constructor
echo 'yb';
$c2 = $container->get(ClassNotbeingCalled::class);
return new AnotherClasse($c1, $c2);
} So basically I see following: I do not have other delegators that should fiddle inbetween. What could be the reason? The same listeners works flawlessly in normal MVC calls. |
On the surface of things, this looks like cyclic dependencies - a listener has a dependency on a service and the service is having listeners registered etc. I will normally try to figure out which listener is causing the cyclic dependency and then either refactor it to remove the dependency, or wrap the listener in a LazyListenerAggregate (Part of the Laminas Event Manager Package) - that way you defer construction of the listener until the event occurs. This is generally better anyway because it means that you don't have to construct a massive dependency graph just to listen for events that might never even get triggered. HTH |
That's a good thought. The aren't real cyclic dependencies, but several of the objects have also events. If the try to reference the EventManager, while it's still instantiating in the delegator, this would cause this cycle. |
Thanks for this, I've just implemented the same in our project and came to a similar issue/conclusion with cyclic dependencies. Ended up injecting the service container into the listener which was causing a problem instead of the actual services as runtime. |
Feature Request
Summary
Currently only events of ModuleManager are processed by laminas-cli, there is no built-in possibility to automatically attach listeners for console events.
Depending on the decision either 'listeners' from module.config.php could be reused or a new key like 'listeners-cli' could be introduced. This way it would be possible to define one console command and then trigger events where other modules could react to it.
The text was updated successfully, but these errors were encountered: