Fix #17: Use Symfony EventDispatcher