The provider should also be private IMO.

The listener cannot be private. The EventDispatcher is retrieving it from the container at runtime to lazy-load it