ColdFusion Application.cfc Tutorial And Application.cfc Reference

Posted May 25, 2007 at 7:22 AM

Tags: ColdFusion

I sometimes do in-house presentations here at Nylon Technology. Last night, I was asked to prepare "something" for this morning. In a mad rush, I threw together this presentation on ColdFusion's Application.cfc component. I am sure most of you have seen this stuff before, and a lot of it is right in the ColdFusion documentation, but for some people at my office, this will be new stuff. I am covering things like Application.cfc events, variables, and some tips and tricks that might not be obvious.

I finished working on this last night at like 9:30 so you better believe I did NOT, nor do I care to proof read this :) It's advertised strickly "as is."


ColdFusion Application.cfc Tutorial For Nylon Technology

ColdFusion MX 7 introduced the Application.cfc ColdFusion component. This component replaces the traditional Application.cfm and OnRequestEnd.cfm ColdFusion application templates. Furthermore, if Application.cfc is present, both of these templates are ignored by the application.

In addition to replacing the request start/end functionality of the old application templates, Application.cfc provides hooks into many additional application level events including:

OnApplicationStart()

This fires when the application first runs. It is a single-threaded method call.

OnSessionStart()

This fires when an individual session first runs. It is a single-threaded method call.

OnRequestStart()

This fires when a page request first runs. It is a single-threaded method call.

OnRequest()

This fires when the requested template needs to get processed.

OnRequestEnd()

This fires at the end of every page request. It is a single-threaded method call.

OnSessionEnd()

This fires at the end of every session. This will fire either for a session timeout or if the server is shutting down. It is a single-threaded method call.

OnApplicationEnd()

This fires at the end of the application. This will fire for an application timeout of if the server is shutting down. It is a single-threaded method call.

OnError()

This fires if an exception gets thrown and is not caught by the controlling code.

All of the above methods are optional. You have an Application.cfc that is completely empty. Also, I say that the above methods are single-threaded which means that you do not have to worry about locking the code within them. However, any and all of these methods can be called explicitly by other parts of the application (ex. calling OnApplicationStart() from OnRequestStart() for manually fired application re-initialization). In this case, the manually invoked events are NOT single-threaded and may be open to race conditions.

In addition to application event hooks, Application.cfc provides public properties that define the application in a manner similar to the CFApplication tag. The following are available THIS-scoped properties:

THIS.Name

This is the name of the application and is used to tie a request to existing application memory scopes.

THIS.ApplicationTimeout

The time span an application will exist before it times out (if the application is not accessed in any way). This defaults to the value set in the ColdFusion administrator.

THIS.SessionManagement

A boolean flag to determine if the SESSION scope should be used. This defaults to false.

THIS.SessionTimeout

The time span a session will exist before it times out (if the application is not access in any way by that session's user). This defaults to the value set in the ColdFusion administrator.

THIS.SetClientCookies

A boolean flag to determine if the CFID and CFTOKEN values are sent as cookies to the client's browser. This defaults to true.

THIS.SetDomainCookies

A boolean flag to determine if the CFID and CFTOKEN values are set for domain and not just a host value. This defaults to false. I have never used this and so I am not exactly sure what this means.

THIS.ClientManagement

A boolean flag to determine if the CLIENT scope should be used. This defaults to the value set in the ColdFusion administrator.

THIS.ClientStorage

If client management is being used, this determines where the client variables are being stored (cooke, registry, or database). This defaults to the value set in the ColdFusion administrator.

THIS.LoginStorage

The place login information is stored (cookie or session). I have never used this, so I am not exactly sure what that means. Defaults to cookie.

THIS.ScriptProtect

A boolean flag to determine if the variables will be protected from cross-site-scripting attacks. Again, I have never used this and I am not sure what it does. This defaults to the value set in the ColdFusion administrator.

Putting it all together, an Application.cfc ColdFusion component skeleton would look something like this:

 Launch code in new window » Download code as text file »

  • <cfcomponent
  • displayname="Application"
  • output="true"
  • hint="Handle the application.">
  •  
  •  
  • <!--- Set up the application. --->
  • <cfset THIS.Name = "AppCFC" />
  • <cfset THIS.ApplicationTimeout = CreateTimeSpan( 0, 0, 1, 0 ) />
  • <cfset THIS.SessionManagement = true />
  • <cfset THIS.SetClientCookies = false />
  •  
  •  
  • <!--- Define the page request properties. --->
  • <cfsetting
  • requesttimeout="20"
  • showdebugoutput="false"
  • enablecfoutputonly="false"
  • />
  •  
  •  
  • <cffunction
  • name="OnApplicationStart"
  • access="public"
  • returntype="boolean"
  • output="false"
  • hint="Fires when the application is first created.">
  •  
  • <!--- Return out. --->
  • <cfreturn true />
  • </cffunction>
  •  
  •  
  • <cffunction
  • name="OnSessionStart"
  • access="public"
  • returntype="void"
  • output="false"
  • hint="Fires when the session is first created.">
  •  
  • <!--- Return out. --->
  • <cfreturn />
  • </cffunction>
  •  
  •  
  • <cffunction
  • name="OnRequestStart"
  • access="public"
  • returntype="boolean"
  • output="false"
  • hint="Fires at first part of page processing.">
  •  
  • <!--- Define arguments. --->
  • <cfargument
  • name="TargetPage"
  • type="string"
  • required="true"
  • />
  •  
  • <!--- Return out. --->
  • <cfreturn true />
  • </cffunction>
  •  
  •  
  • <cffunction
  • name="OnRequest"
  • access="public"
  • returntype="void"
  • output="true"
  • hint="Fires after pre page processing is complete.">
  •  
  • <!--- Define arguments. --->
  • <cfargument
  • name="TargetPage"
  • type="string"
  • required="true"
  • />
  •  
  • <!--- Include the requested page. --->
  • <cfinclude template="#ARGUMENTS.TargetPage#" />
  •  
  • <!--- Return out. --->
  • <cfreturn />
  • </cffunction>
  •  
  •  
  • <cffunction
  • name="OnRequestEnd"
  • access="public"
  • returntype="void"
  • output="true"
  • hint="Fires after the page processing is complete.">
  •  
  • <!--- Return out. --->
  • <cfreturn />
  • </cffunction>
  •  
  •  
  • <cffunction
  • name="OnSessionEnd"
  • access="public"
  • returntype="void"
  • output="false"
  • hint="Fires when the session is terminated.">
  •  
  • <!--- Define arguments. --->
  • <cfargument
  • name="SessionScope"
  • type="struct"
  • required="true"
  • />
  •  
  • <cfargument
  • name="ApplicationScope"
  • type="struct"
  • required="false"
  • default="#StructNew()#"
  • />
  •  
  • <!--- Return out. --->
  • <cfreturn />
  • </cffunction>
  •  
  •  
  • <cffunction
  • name="OnApplicationEnd"
  • access="public"
  • returntype="void"
  • output="false"
  • hint="Fires when the application is terminated.">
  •  
  • <!--- Define arguments. --->
  • <cfargument
  • name="ApplicationScope"
  • type="struct"
  • required="false"
  • default="#StructNew()#"
  • />
  •  
  • <!--- Return out. --->
  • <cfreturn />
  • </cffunction>
  •  
  •  
  • <cffunction
  • name="OnError"
  • access="public"
  • returntype="void"
  • output="true"
  • hint="Fires when an exception occures that is not caught by a try/catch.">
  •  
  • <!--- Define arguments. --->
  • <cfargument
  • name="Exception"
  • type="any"
  • required="true"
  • />
  •  
  • <cfargument
  • name="EventName"
  • type="string"
  • required="false"
  • default=""
  • />
  •  
  • <!--- Return out. --->
  • <cfreturn />
  • </cffunction>
  •  
  • </cfcomponent>

Now that we understand how all the events and variables are wired together, let's take a closer look at the individual application event methods.

OnApplicationStart()

This is the perfect place to define application-scoped variables (ex. APPLICATION.DSN for data source structures). If this method is invoked manually, be sure to call StructClear() on the APPLICATION scope before you re-initialize the data values. This will help to ensure a clean refresh.

The return boolean signals as to whether or not the application loaded successfully. Returning false will halt the processing of the rest of the events of the current page request.

OnSessionStart()

This is the perfect place to define session-scoped variables (ex. SESSION.Cart for eCommerce cart data). If this method is invoked manually, be sure to call StructClear() on the SESSION scope before you re-initialized the data values. HOWEVER! before clearing the scope, get a copy of the CFID/CFTOKEN values so that you can store them back into the session during re-initialization. ColdFusion will not automatically re-create these values as calling this event method is not actually restarting the session.

OnRequestStart()

This the perfect place to define request-specific and other request-scoped variables (ex. REQUEST.Attributes for the union of the FORM/URL scopes). This is also a good place to do universal FORM value scrubbing (such as removing smart quotes and trimming form field values).

If you application or sessions can handle manual re-initialization, this is a good place to check for those URL flags (ex. StructKeyExist( URL, "resetApp" )) and then manually invoke the OnApplicationStart() or OnSessionStart() application events.

If you are using the OnRequest() method and you expect this application to be used for flash remoting or CFC-based web service calls, this is the ideal time at which to check for the request type (standard page request vs. web service) and if need be, delete the OnRequest() method from the Application.cfc (ex. StructDelete( THIS, "OnRequest" )).

If the return value is false, the page processing will be halted.

OnRequest()

If you include this event then you must include the requested page via a CFInclude tag. The relative path of the template is passed as the only argument to this function. If you include the in this manner, the processed template becomes what is essentially a "Mix-In" of the Application.cfc meaning that it is actually part of the Application.cfc code. If you do this, the processed page will have access to the THIS and VARIABLES scope of the Application.cfc.

If the request page is included in this manner, it also means that the requested page will have access to all methods defined in the Application.cfc.

This is the perfect place to handle login management. Since this method determines which template gets executed, this is where you can check login status and conditionally include the login template rather than the requested template.

OnRequestEnd()

This is the perfect place to handle page logging. By doing it here (especially if the first command is a CFFlush tag), the user experience will not be affected by any processing overhead of this event method.

OnSessionEnd()

This is the perfect place to clean up sessions that have times out (ex. deleting uncommitted shopping cart information). This method does not have inherent access to the APPLICATION scope or the SESSION scope (as the OnRequestEnd() method has access to the REQUEST scope). In order to access those scopes, you must use the passed in arguments.

OnApplicationEnd()

This is the perfect place to log information about the application. This method does not have inherent access to the APPLICATION scope. In order to access that scope, you must used the passed in argument.

OnError()

This event gets called when an event fires and allows you to handle that error and include an error handling template if you so desire. However, this event cannot display anything to the user if the error occurs during the OnApplicationEnd() or OnSessionEnd() events as those are not request-related (unless called explicitly during a request).

One thing to be aware of (as of MX7) is that the CFLocation tag throws a runtime Abort exception (which makes sense if you understand that the CFLocation tag halts the page and flushes header information to the browser). As a work around to this, you can check the passed in Exception type and if its a Abort exception do not process the error:

 Launch code in new window » Download code as text file »

  • <cfif NOT CompareNoCase(
  • ARGUMENTS.Exception.RootCause.Type,
  • "coldfusion.runtime.AbortException"
  • )>
  •  
  • <!--- Do not process this error. Return out. --->
  • <cfreturn />
  • </cfif>

As a note of caution, if you use the OnError() event method to include a ColdFusion template that is also URL-accessible, you have to put in logic that knows not to use exception-related values if the template is access directly.

Additional Methods

The above event methods are those that the ColdFusion server will attempt to hook into during the application and page life cycle. Application.cfc is a ColdFusion component just like any other CFC file and because of that, there is nothing to stop you from defining as many methods in it that you want. One thing that I like to do sometimes is create a method CreateCFC() within the Application.cfc to provide short hand notation (and other benefits) not only to the other Application.cfc methods but also to any template that shares the Application.cfc memory scopes.

In addition to methods, you can create as many variables as you like within the Application.cfc memory scopes.

What Is A ColdFusion Application?

ColdFusion applications do not really exist. At least not in the way you might think of a traditional desktop application that has a running process. ColdFusion applications do not have a constant process. Instead, they have memory scopes. Each application has its own name which ties it to a chunk of memory somewhere. Every time you define an application through the Application.cfc (or CFApplication), what you are really doing it associating the current page request to the chunk of memory that is associated with that application name.

When you start to look at ColdFusion applications this way, it becomes a little more clear why you cannot explicitly kill an application or a session; there simply is nothing to kill. An application doesn't run unless you have a running page that requests to be associated with it.

When Does The Application.cfc Get Created?

It is important to understand that Application.cfc is newly instantiated for every single page request. This means that all the application settings and page request settings can be different for every page request. This information can be used to set up alternate session management configurations. For example, you might set THIS.SessionManagement to false for browsers that you know cannot accept cookies (and therefore cannot handle session management).

What If I Am In A Rush - Isn't CFApplication Easier To Code Than Application.cfc

This is absolutely not true. Remember, all of the information outlined in this presentation is completely optional. You don't have to have anything in your Application.cfc. For example, the following is a perfectly valid Application.cfc:

 Launch code in new window » Download code as text file »

  • <cfcomponent>
  • <cfset THIS.Name = "TinyApp" />
  • </cfcomponent>

Can you get any more simple than that? This is just as easy as the CFApplication tag, but if you go the Application.cfc route, you will have the advantage of being able to easily add in the other application event methods as you need them.

Download Code Snippet ZIP File

Comments (34)  |  Post Comment  |  Ask Ben  |  Permalink  |  Other Searches  |  Print Page




I'm Too Young For This!

Reader Comments

Thanks for the overview. I've got a couple of questions from trying to use Application.cfc.

First, do you set things in the application scope such as your datasource name and then do an application lock every time you need to call it? Or do you dump it into some other non-locking scope when you need it?

Second, when you run the onSessionStart() call, how do you get access to the variables that you create? For example, I have some queries that need to run only when a session starts but I want to cache them in some scope other than the session scope because they are called frequently and I prefer not to use all those locks. Or am I worrying about excessive locking for no reason?

For example, I would like to run this query:

<cfquery name="Request.getSystemSettings"
datasource="#request.ds#"
debug
cachedwithin="#CreateTimeSpan(1,0,0,0)#">
EXEC pr_getSystemSettings '#cgi.http_host#'
</cfquery>

onSessionStart() but I don't seem to have access to the query results outside of the cfc.

Posted by Ian on May 25, 2007 at 8:17 AM


"First, do you set things in the application scope such as your datasource name and then do an application lock every time you need to call it? Or do you dump it into some other non-locking scope when you need it?"

You do not need to lock variables set in onApplicationStart. CF single threads it for you.

Later on, if you want to read the values, then you do not need to lock them if they are simple constant variable (like DSN and most app variables.)

"Second, when you run the onSessionStart() call, how do you get access to the variables that you create? For example, I have some queries that need to run only when a session starts but I want to cache them in some scope other than the session scope because they are called frequently and I prefer not to use all those locks. Or am I worrying about excessive locking for no reason?"

You can access the Application scope in onSessionStart, but you would want to ensure you use cflock if you are updating the app scope.

Posted by Raymond Camden on May 25, 2007 at 8:29 AM


@Ian,

As Ray said, you do not need to lock the variable since OnApplicationStart() is inherently single-threaded. However, if you call OnApplicationStart() manually, then it is being called as if it were a regular, every day function:

<cffunction name="OnRequestStart">

<cfif SturctKeyExist( URL, "reset" )>
<cfset THIS.OnApplicationStart() />
</cfif>

</cffunction>

In this case, since we are manually trying to reset the application and not letting the ColdFusion application server call it when the app *starts*, then OnApplicaitonStart() is not single threaded.

Because I usually have something like this going on in my applications, I tend to put an APPLICATION-scoped CFLock in my OnApplicaitonStart() method. At the very least, it cannot hurt.

As far as the scopes to use, sorry about that - my presentation did not go into good detail about that - you would use the same scoping that you would in a traditional CFApplication / Application.cfm scenario:

<cfset APPLICATION.DSN = StructNew() />
<cfset APPLICATION.DSN.Source = "cool_db" />

<cfset SESSION.User = StructNew() />
<cfset SESSION.User.ID = 0 />

You can use APPLICAITON, SESSION, REQUEST, and all the other scope within the Application.cfc just as you would have with the Application.cfm (although not all are available in all the event methods).

As far as using the query results set in OnSessionStart() outside of the CFC, the problem here is that OnSessionStart() is not related to any given page request - it's a session-specific event.

If you want to create objects in an application-level event and then use them on the rest of the page processing, do that stuff in OnRequestStart() or even OnRequest().

And, like Ray said, as far as locking goes, if you are reading simple value, don't worry about locking. Locking has overhead and should only be used if you KNOW a race condition might occur (a race condition is that one thread might be reading a chunk of code while another thread might be trying to update variables within that chunk of code). If you know that NO other thread will ever update something like DSN values, then don't worry about locking.

Even if you are manually restarting the application (calling OnApplicationStart()), which could potentially cause a race condition, I would still say don't worry about it as that is a very small possibility and something that will happen only rarely.... and of course, evaluate the worst case scenario - let's say you are updating the DSN and some dude in Delaware gets a CF error cause he was trying to do a query just as you cleared the APPLICATION scope... and then he refreshes the page and it works... is getting rid of that chance WORTH the overhead of locking every single read of the DSN?

Posted by Ben Nadel on May 25, 2007 at 8:49 AM


So for the various query result sets and string values that don't change I can put them in the application scope and not worry about locking because nothing bad can happen?

What would you recommend for the query example I gave that should only be called when the session starts but because it is dynamic gets called on every page request? I can't really dump it to the session scope because the values are used on just about every page of the site.

Posted by Ian on May 25, 2007 at 9:29 AM


On a styling note, do you create the structures in your example so that it is easier to delete them later instead of having to reference each individual value?

Posted by Ian on May 25, 2007 at 10:01 AM


@Ian,

As far as the query goes, if it needs to be executed for every single page request, then put it in the OnRequestStart() event method. Since that method is called once per page request (unless called manually which I have never seen done), it is essentially single threaded and you will NOT have to worry about locking.

Scoping it directly into the REQUEST scope, as you have done, is valid, and is what I would do.

However, look at what it is doing... it is getting results based on the http_host value. This data, while it may change depending on the host, will NOT change across a user's page requests. In that case, I would put the query in the OnSessionStart() event method and scope it directly into the SESSION scope:

<cfquery name="SESSION.GetSystemSettings">...</cfquery>

Of course, you might take this even one step further; if this is going to be the same for a TON of people, no need to keep going back to the database right? Instead, in your OnSessionStart(), you can try to cache it in the APPLICATION scope:

<cffunction name="OnSessionStart">

<cfif NOT StructKeyExists( APPLICATION.SystemSettings, CGI.http_host )>

<cfquery name="qSystemSettings"></cfquery>

<cfset APPLICATION.SystemSettings[ CGI.http_host ] = qSystemSettings />

</cfif>

<cfset SESSION.SystemSettings = APPLICATION.SystemSettings[ CGI.http_host ] />

</cffunction>

What I am doing there is creating a system settings query object for each http_host that comes in and caching it in the APPLICATION scope. Then, for each session, I check to see if that setting object exists yet. If NOT, I created it and cached it. Then after that conditional check, I know that it exists and can then just get a reference to it in my session.

As far as using Structs vs. individual values, I like using structs cause I can logically group related data. This makes my code more readable (IMO) and also makes it easier to pass data; it's less code to pass a structure containing 10 values than to pass all 10 values.

Hope some of that helps.

Posted by Ben Nadel on May 25, 2007 at 10:15 AM


Hi Ben,

Yet another great overview. Thanks for the effort.

Could you make your web pages more print-friendly?

Posted by William from Lagos on May 25, 2007 at 11:12 AM


@Will,

Glad it helped. I am going to work on making a print-friendly version of my blog detail pages. Thanks for bearing with me.

Posted by Ben Nadel on May 25, 2007 at 11:23 AM


Ben - great post! I'm building an quick application using Ray Camden's Soundings survey application and decided to try to convert his application to use application.cfc - and so far so good but I have run into one issue I'm not sure how best to handle - nested application.cfms...

He has an /admin section where he has another application.cfm which include the one in the root. I've done this myself in the past but not sure the best way to handle it in moving over to application.cfc...

Any thoughts?

Thanks again for all the great blog posts! I don't know how you find the time!

Posted by Jim Priest on May 31, 2007 at 4:01 PM


@Jim,

Glad you like the work and effort that I am putting into this stuff. I know that you can extend one Application.cfc with another, however, if they are in nested directories, that will require a mapped path. I have never done this so I cannot give you any real advice other then Google "extending Application.cfc".

Posted by Ben Nadel on May 31, 2007 at 4:53 PM


Adobe has a full tech note on this. Search at GOogle. Sean Corfield also blogged on it.

Posted by Raymond Camden on May 31, 2007 at 4:57 PM


I bugged Ray about it and he pointed me to Sean's blog where indeed he has the answer!

http://corfield.org/blog/index.cfm/do/blog.entry/entry/Extending_Your_Root_Applicationcfc

Posted by Jim Priest on May 31, 2007 at 7:17 PM


Just wanted to mention I copied your onError code as is and got an error that ARGUMENTS.Exception.RootCause.Type doesn't exist. I'm not sure you typed something wrong or my CF installation is different somehow, but RootCause doesn't exist as a key to Exception for me. There's Exception.Type, which is just a name, not something like coldfusion.runtime... Anyway, thought I'd mention this just in case.

Posted by Thomas Messier on Jul 19, 2007 at 11:01 AM


Yes, you need to check for the existence first. I make the mistake all the time myself.

Posted by Raymond Camden on Jul 19, 2007 at 11:04 AM


Yes Thomas you're right.

I noticed it only exists if your Application.cfc contains the onRequest method.

Posted by William from Lagos on Jul 19, 2007 at 11:17 AM


Interesting. Very interesting. I have to say that I pretty much always use OnRequest() so I have never noticed this. Very good to know. Thanks.

Posted by Ben Nadel on Jul 19, 2007 at 11:25 AM


@Thomas,

Thanks for the tip. I did a quick little example to see what was different:

http://www.bennadel.com/index.cfm?dax=blog:853.view

Posted by Ben Nadel on Jul 23, 2007 at 9:28 AM


Hi,
I am going through converting an application.cfm to an application.cfc and am running into variables that are set in the variables scope in the application.cfm (used to be accessible in all pages of the application).

Now those variables are not accessible when I set them in the onRequestStart() or outside all the methods of Application.cfc.

The only thing I could think of to make the variables accessible from all application pages is to put them in the application or the request scope.

The problem is that I will have to add a <cfparam ..> at the top of each page that uses the variable to initialize the local variable with application/request scope variable. Can you think of anything simpler than that to accomplish the same thing?

Posted by Ahmed El-Rasheedy on Aug 15, 2007 at 1:36 PM


If yo use onRequest, then any variables you set will be in the Variables scope. This also has the side of effect of breaking Flash Remoting and Web Services, and copying other info from the CFC. Personally - I'd just use Request variables. It will help them stand out from variables made on the page itself.

Posted by Raymond Camden on Aug 15, 2007 at 1:40 PM


Thanks Raymond.

Posted by Ahmed El-Rasheedy on Aug 15, 2007 at 1:49 PM


Are you using the OnRequest() event method? That is the only way that the VARIABLES scope of the Application.cfc would be available in the processing template.

Posted by Ben Nadel on Aug 15, 2007 at 2:23 PM


I was not using the onRequest(). I was only using onRequestStart().
I think I may end up using the onRequest() though since there are many files to update if I use the Application/Request scope vars. The two scenarios that would be affected by using the onRequest() - Flash Remoting and WS do not apply to my app. Thanks for the info.

Posted by Ahmed El-Rasheedy on Aug 15, 2007 at 3:41 PM


@Ahmed,

No problem. And also, FYI, you can always conditionally delete the OnRequest() method if it is a CFC-based method call for flash remoting. But if that doesn't affect you, don't worry about it.

Posted by Ben Nadel on Aug 15, 2007 at 4:05 PM


Interesting Ben, how an that be done? (deleting onRequest method when making a Flash remoting or web services call)

Posted by William from Lagos on Aug 16, 2007 at 9:24 AM


@William,

In the OnRequestStart() method, you can check the requested template. If it is a given file type (ex. .CFC) or in a certain directory or something, you can simply delete the function from the CFC scope:

StructDelete( THIS, "OnRequest" )

Then, when the ColdFusion application server finishes executing the OnRequestStart() method, it will look for OnRequest(), but it will no longer exist for that page request.

Posted by Ben Nadel on Aug 16, 2007 at 10:11 AM


Cool! Rule of the thumb, CFCs are objects whose properties, variables and methods can be dynamically created or removed (as in this case) at runtime.

Posted by William from Lagos on Aug 16, 2007 at 12:41 PM


Yeah, pretty much. CFCs are super flexible that way.

Posted by Ben Nadel on Aug 16, 2007 at 12:45 PM


I have now tryed to use the Application.cfc. But in my code I uses cfc's in a sub catalog to make query requests.
But the problem is now that the cfc's cant see the application.DNS!?
Why is that?

Posted by Morten Kruse on Oct 9, 2007 at 4:52 AM


I think it depends on what you mean. You say you use CFCs in a sub catalog - do you mean subdirectory? As you know, if CF can't find an App.cfc/cfm in the current folder, it will look up higher in the directory until it finds one - so it should have no problem finding your App.cfc and if yo have app.dsn defined there, all should be well.

But - you really shouldn't be using "outside" variables in your CFCs. Why not let your App.cfc create an instances of the CFC in onApplicationStart? When you make the instance, pass in the DSN value so the CFC can store it inside itself.

Posted by Raymond Camden on Oct 9, 2007 at 7:11 AM


Yes I ment subdirectory.
Today I tryed to use Application.cfc again and now it worked!?
I don't know what caused the problem last time.

But your sugestion about using Application.cfc to create an instance of the cfc's that I uses sounds like a very good idea.
But how would you do that? And how should they be called from the code?
Today I call the cfc's by <cfinvoke ../>

Posted by Morten Kruse on Oct 9, 2007 at 7:32 AM


Typically you add a method named init to your cfcs. This method takes any configuaration parameter, like DSN. Then in App.cfc you can do
(note app = application)

cfset app.mycfc = createObject("component","path.to.your.cfc.name").init(app.dsn)>

Posted by Raymond Camden on Oct 9, 2007 at 7:45 AM


Hey Ben, Good stuff but are you sure you receive the application scope as a variable?

Also I have another question, I define a lot of high level stuff in those methods, yet they're completely accessible to the included template. If I don't want designers muddling with that logic, how can I make them private or inaccessible in the template's scope?

access="private" doesn't work in function definition, because the included template has private access.

Posted by Matt Foster on Jan 21, 2008 at 10:33 AM


@Matt,

If you don't want the include to have access to the Application.cfc data, don't use the OnRequest() event method. If you exclude that method, then the requested page will simply run; but, since it is not creating a CFC mixin, then you won't have to worry about access.

If you have to use the OnRequest() event method (which I think is a wonderful method), then there is not much you can do.

What are you worried about? Developers messing with cached variables or something? I can assure you that whatever you are doing, even without the CFInclude of the requested template, developers could mess with cached data. The OnRequest() event method does not really change that at all.

I guess the variables stored in the Applicaiton.cfc via the THIS or VARIABLES scope, that is something that is OnRequest() enabled...

Posted by Ben Nadel on Jan 23, 2008 at 10:13 AM


Hi Ben

great tutorials and files (as ever). Thank you for everything you blog and share.

I'm a CF developer of over two years, but (ashamed to say) never used application.cfc before.
I am also on a CF8 server, and want to create a mapping to a directory to use for custom tags. I have heard that this can be done per application, but I cannot seem to get it working. I currently have the site I am working on in a /V2/ folder, with the application.cfc within.
How can I create a mapping from the .cfc to a directory to create a custom tag path?

Many thanks,

Matt

Posted by Matt on Jan 29, 2008 at 6:38 AM


Post Comment  |  Ask Ben


Home   |   Web Log   |   ColdFusion   |   Projects   |   Resume   |   Job Form   |   Search   |   Contact
Epicenter Consulting - Custom Software Solutions for Business Evolution HostMySite.com - The Leader In ColdFusion Hosting