Use Events for zf3/laminas

In zf2 i use DelegatorFactory for add event listeners to services, controllers and etc. Now update framework to zf3 (3.0.0) and have problem with all events in listeners.

This line broken my site https://github.com/laminas/laminas-mvc/blob/3.2.x/src/Service/ServiceManagerConfig.php#L98 . Because i don’t have SharedManager in EventManager.

Simple code for service factory:

public function __invoke(ContainerInterface $container, $requestedName, array $options = null): Order
{
    $service = new Order(
        $container->get(Warehouse::class),
        $container->get(Receiver::class),
        $container->get(Product::class)
    );

    $eventManager = $service->getEventManager();

    /** @var OrderMailListener $mailListenner */
    $mailListenner = $container->get(OrderMailListener::class);
    $mailListenner->attach($eventManager);

    $orderLogListener = $container->get(OrderLogEvents::class);
    $orderLogListener->attach($eventManager);

    return $service;
}

And simple code for delegators:

public function __invoke(ContainerInterface $container, $name, callable $callback, array $options = null)
{
    /** @var AbstractService $service */
    $service = call_user_func($callback);
    $eventManager = $service->getEventManager();

    /** @var OfficeSenderEvents $agregate */
    $agregate = $container->get(OfficeSenderEvents::class);
    $agregate->attach($eventManager);

    return $service;
}

it looks like https://docs.mezzio.dev/mezzio/v3/features/container/delegator-factories/
How can I correctly subscribe to events? Initializer EventManagerAwareInitializer kills all my listener settings (((

Hello and welcome to our forums! :smiley:

Can you describe the problem? Do you get any error messages?
Thanks in advance!

Hello! There are no error messages. The problem is most likely that I am not correctly subscribing to events.
I tracked the creation of the service factory in the debugger.

  1. A service class is created (implements EventManagerAwareInterface), an event is added. Since there is no EventManager, it is created. But with an empty SharedManager.
  2. Delegators are connected who can also add a subscription to events.
  3. After the delagators comes the initializer, which sees that there is no SharedManager and clears all my events.

This change was made 5 years ago.


So far I have only 1 solution - in each factory add a SharedManager from the container. But this is not very convenient.

This is a custom class / service, right? Can show the related code for this class? I think you create a separate event manager without the a shared event manager therefore the event manager instance from the application is set to your class / service.

My service

class MyService implements EventManagerAwareInterface
{
    use EventManagerAwareTrait;

   protected $warehouseService;

    public function __construct(Warehouse $warehouseService)
    {
      $this->warehouseService = $warehouseService;
    }

    ....
    public function saveOrder(OrderEntity $order)
    {
      $this->getEventManager()->trigger('onSaveOrder', $this, ['entity' => $_order]);
    }
}

Factory service:

public function __invoke(ContainerInterface $container, $requestedName, array $options = null): Order
{
    $service = new MyService(
        $container->get(Warehouse::class)
    );

    $eventManager = $service->getEventManager();

    //Send mail manager, user etc for event onSaveOrder
    $mailListenner = $container->get(OrderMailListener::class);
    $mailListenner->attach($eventManager);

    return $service;
}

Delegators:

public function __invoke(ContainerInterface $container, $name, callable $callback, array $options = null)
{
    $service = call_user_func($callback);
    $eventManager = $service->getEventManager();

    //Save logs for user action in office
    $agregate = $container->get(OfficeLogger::class);
    $agregate->attach($eventManager);

    return $service;
}

Config file:

        'delegators' => [
            MyService::class => [
                OfficeLoggerDelegator::class,
            ],
           OrderController::class => [
                OfficeLoggerDelegator::class,
            ],
        ],

As a result, it turns out that everything worked until version 2.7. In version 3 EventManagerAwareInitializer cleans up everything I did in the factory and deligator.
A similar problem is described here
It turns out that I have to inject the EventManager from the container into each class in the factory.
Why is the SharedManager necessary?
Instead of doing it in the initializer and forgetting. I will do this in every factory.