Symfony and Legacy Code: EventDispatcher and legacy hooks

The Symfony EventDispatcher component is among the simplest yet extensively used both by Symfony itself and by application code. Its function is very simple: there is one central EventDispatcherInterface service, which can dispatch arbitrary events (defined by name and optionally by an instance of Event-derived class), and register listeners for these events. EventDispatcher is invaluble in writing extensible, loosely coupled code.

A good example of EventDispatcher use is Symfony’s central HttpKernel class, which, as we saw before, transforms a HTTP Request into a Response. It does that by resolving and executing a controller function. Controllers are typically mapped to URLs via Routing component; however HttpKernel is entirely unaware of Routing classes and their implementation. Instead there is a RouterListener class which glues Routing to HttpKernel by locating appropriate controller name, and setting _controller attribute on Request (or throwing a NotFoundHttpException if no routes match the request). HttpKernel may then resolve controller name to an actual controller function and its arguments using default ControllerResolverInterface implementation, and call this function to render a Response.

That’s all fine and good, but sizable legacy applications attempting to be somewhat extensible typically implement some kind of events/hooks/whatever-they-call-it system themselves. So can we route the legacy hook APIs through EventDispatcher? Why of course we can.

Continue reading “Symfony and Legacy Code: EventDispatcher and legacy hooks”