I ran into something a bit strange the other day when I was playing around with a dynamic Application.cfc proxy. I tried, in the pseudo constructor of the Application.cfc (the space before the CFFunction tags), to delete the OnRequest() event method. While this appears to work if you dump out the Application.cfc object, it does not prevent the events from being triggered. Take a look at this example:
<cfcomponent output="true" hint="I define the application and listen for application level events."> <!--- In the pseudo constructor, we are going to try and delete the following methods. ---> <cfset StructDelete( THIS, "OnRequestStart" ) /> <cfset StructDelete( THIS, "OnRequest" ) /> <!--- ASSERT: At this point, we should have deleted the OnRequest() and OnRequestStart() event listeners. We should only have the OnRequestEnd() event listener left. ---> <!--- Dump out this reference to see if the methods were successfully deleted from the Application.cfc. ---> <cfdump var="#THIS#" label="Application.cfc THIS Scope" /> <cffunction name="OnRequestStart" access="public" returntype="boolean" output="true" hint="I run before a template is executed."> <p> I am the OnRequestStart() event listner. </p> <!--- Return out. ---> <cfreturn true /> </cffunction> <cffunction name="OnRequest" access="public" returntype="void" output="true" hint="I execute the page template."> <p> I am the OnRequest() event listner. </p> <!--- Include passed in page. ---> <cfinclude template="#ARGUMENTS[ 1 ]#" /> <!--- Return out. ---> <cfreturn /> </cffunction> <cffunction name="OnRequestEnd" access="public" returntype="void" output="true" hint="I run after a template has been executed."> <p> I am the OnRequestEnd() event listner. </p> <!--- Return out. ---> <cfreturn /> </cffunction> </cfcomponent>
Notice that at the top of the Application.cfc we are deleting the OnRequestStart() and the OnRequest() event listener methods. This should leave just the OnRequestEnd() method. This should also mean that the OnRequestStart() and OnRequest() methods won't fire (seeing as they have been deleted). However, when we run this page, here is the output that we get:
Notice that in the CFDump of our Application.cfc instance, the OnRequestStart() and OnRequest() have, in fact, been deleted. Realize that this is also the very first thing that displays meaning that this execution has been completed first. Notice also, and here is the oddity, that the page output also contains the text from the OnRequestStart() and OnRequest() event methods, indicating that those two methods have been executed.
It seems that you can't alter the method configuration of the Application.cfc from the pseudo constructor. I am not saying that you should do this, I am saying you can't do this. What's really odd, however, is that you can, from the OnRequestStart() method, successfully delete the OnRequest() event method. This is how we can dynamically cope with web service calls. However, the OnRequestStart() event method executes after the pseudo constructor, so it really makes no sense as to why the delete method gesture would be more successful later on in the execution path.
Want to use code from this post? Check out the license.