Scaffolding a Generic Admin - Part 4 - Introduction to Dispatcher
Posted by Paul Marcotte | Tags: Dispatcher
If you've been following along with this series, you might be wondering just what is Dispatcher? I like to think of Dispatcher as an Event Delegation package that provides some simple components to build event driven web applications. For those familiar with Colin Moock's seminal book on object oriented development for Flash "Essential ActionScript 2.0", Dispatcher is my attempt to port the Delegation Event Model example found in EAS2 to ColdFusion...Before I get into the hows of Dispatcher, I'd like to point out that it bears resemblance to other ColdFusion MVC frameworks. My intention for releasing Dispatcher is not to compete with other frameworks, but rather to provide an introductory level Front Controller implementation that developers who are new to frameworks can use to learn the concepts and architecture behind MVC and/or Front Controller. Dispatcher will likely grow into a more mature product over time. Presently, it is simple by intention. The class diagram below gives an overview of a Dispatcher app.
Here's a breakdown of the major players.
DispatcherConfig is simple configuration object where you can store application constants such as mail server details, default locales, etc. So, instead of using the application scope to store these details, you would store them in the DispatcherConfig object. The configuration values stored here can be accessed within your controllers or views via the RequestEvent getConfig('key') method.
Dispatcher is essentially a front controller that registers listeners (stored in the composed EventListenerList). It has only a few public methods. The most important of which is getRequestEvent(), which is invoked for each page request. The getRequestEvent() method creates a RequestEvent object which it passes to its registered listeners (via their onRequest() method).
UserController and ViewManager are example listeners which extends the RequestListener class. All components that extend RequestListener override the onRequest() method.
RequestEvent is an event object that stores data that will be acted upon by controllers and ultimately displayed within views.
Dispatcher uses a event-driven (also known as "implicit invocation") methodology. Every request is expected to have a url variable in the format cmd={object}.{action}. Where Dispatcher differs from some other frameworks in this regard, is that not all requests are made to a single page (typically index.cfm). You can have any number of pages, each with a unique layout if desired.
Here's an example of the onRequestStart() method of Application.cfc for an application that uses Dispatcher.
<cffunction name="onRequestStart" returnType="boolean" output="false">
<cfargument name="thePage" type="string" required="true">
<!--- copy session scope --->
<cflock scope="Session" type="readonly" timeout="20">
<cfset sessionCopy = StructCopy(Session) />
</cflock>
<!--- generate an event object and put it into Request scope--->
<cfset Request.event = application.dispatcher.getRequestEvent(arguments.thePage,url,form,cookie,sessionCopy) />
<cfreturn true>
</cffunction>
To get an idea of what happens within a Dispatcher application, let's look at the request life cycle.
1. At the beginning of a request, onRequestStart() is invoked. The getRequestEvent() method of Dispatcher is likewise invoked with the arguments: thePage,url,form,cookie,sessionCopy.
2. Dispatcher creates a new RequestEvent object then loops through its listener list and invoking the onRequest() method on each, supplying RequestEvent as an argument.
3. Listeners add to, or ignore the event object based on switch/case blocks within onRequest().
4. The ViewManager is the final listener in the cycle and it prepares the views to be included in a layout file. For any given page, I might have menu, content, footer and header areas. Based on the page that is called and the event command, the ViewManager will add views to the event object by defining the path to an include file. If the event has errors, the ViewManager will also define an "ErrorView".
5. At the end of the cycle, Dispatcher returns the RequestEvent object which is placed in the Request scope as "Request.event".
I have enclosed the latest version of Dispatcher 0.1 beta. In it you'll find the components described above in the class path "com.fancybread.event" and a word doc which contains more instructions on how to setup Dispatcher and the included "hello world" sample application. I'll break down the setup process as it relates to a generic admin over the next couple of posts.
Questions and comments are welcome. I must admit that I have worked on this long enough to understand the process, but not sure whether this intro will make sense to a newcomer...
There are no comments yet...Kick things off by filling out the form below.
Leave a Comment