protected function getEventListenerCallback($listenerConfig, IContainer $container) : callable
    {
        if (is_callable($listenerConfig)) {
            return $listenerConfig;
        }

        if (is_string($listenerConfig)) {
            if (strpos($listenerConfig, '@') === false) {
                throw new InvalidArgumentException("Listener data \"$listenerConfig\" is incorrectly formatted");
            }

            list($listenerClass, $listenerMethod) = explode('@', $listenerConfig);

            return function ($event, $eventName, IEventDispatcher $dispatcher) use (
                $container,
                $listenerClass,
                $listenerMethod
            ) {
                $listenerObject = $container->resolve($listenerClass);
                $listenerObject->$listenerMethod($event, $eventName, $dispatcher);
            };
        }

        throw new InvalidArgumentException(
            'Listener config must be either callable or string formatted like "className@methodName"'
        );
    }