<listener name="broadcast" type="MessageListener">
<parameters>
<parameter name="some.message" value="listenerA.method1,listenerB.method2" />
<parameter name="another.message" value="listenerA.method3" />
</parameters>
</listener>
Here's how you broadcast a message:
<parameters>
<parameter name="some.message" value="listenerA.method1,listenerB.method2" />
<parameter name="another.message" value="listenerA.method3" />
</parameters>
</listener>
<notify listener="broadcast" method="some.message" />
Finally, here's the MessageListener.cfc:
<cfcomponent extends="MachII.framework.Listener" output="false">
<cffunction name="onMissingMethod" returntype="void" access="public" output="false">
<cfargument name="missingMethodName" />
<cfargument name="missingMethodArguments" />
<cfset var listenerList = getParameter(arguments.missingMethodName) />
<cfset var listenerManager = getAppManager().getListenerManager() />
<cfset var listener = 0 />
<cfset var event = 0 />
<cfif structKeyExists(arguments.missingMethodArguments,"event")>
<cfset event = arguments.missingMethodArguments.event />
<cfelse>
<cfset event = arguments.missingMethodArguments[1] />
</cfif>
<cfloop index="listener" list="#listenerList#">
<cfinvoke component="#listenerManager.getListener(listFirst(listener,"."))#"
method="#listLast(listener,'.')#"
returnvariable="result"
event="#event#" />
</cfloop>
</cffunction>
</cfcomponent>
Yes, it relies on ColdFusion 8's onMissingMethod() handler so that the MessageListener can respond to any message (i.e., any method call) and it uses the method name to look up the mapping to listeners and methods to be called.<cffunction name="onMissingMethod" returntype="void" access="public" output="false">
<cfargument name="missingMethodName" />
<cfargument name="missingMethodArguments" />
<cfset var listenerList = getParameter(arguments.missingMethodName) />
<cfset var listenerManager = getAppManager().getListenerManager() />
<cfset var listener = 0 />
<cfset var event = 0 />
<cfif structKeyExists(arguments.missingMethodArguments,"event")>
<cfset event = arguments.missingMethodArguments.event />
<cfelse>
<cfset event = arguments.missingMethodArguments[1] />
</cfif>
<cfloop index="listener" list="#listenerList#">
<cfinvoke component="#listenerManager.getListener(listFirst(listener,"."))#"
method="#listLast(listener,'.')#"
returnvariable="result"
event="#event#" />
</cfloop>
</cffunction>
</cfcomponent>

3 responses so far ↓
1 Joel Cox // Aug 29, 2007 at 4:57 AM
Perhaps the Mach-II approach is less flexible, but I know exactly which method that I'm invoking.
2 Sean Corfield // Aug 29, 2007 at 2:20 PM
In Model-Glue - as in my example above - the event handler "broadcasts" a message and the framework looks up which methods in which controllers are declared to listen for that message and calls them.
I tend to recommend messages are named "needFoo", "needBar" so that it emphasizes the distinction between message names and method names (which are often "getFoo" and "getBar").
3 Sean Corfield // Jan 1, 2008 at 5:42 PM
Leave a Comment