Per-Application Mappings

February 15, 2010

This is nothing new, but I was reviewing some code the other day and noticed that the developer hadn't used per-application mappings, so thought I'd blog about them in-case it is useful to other people who don't know about this handy feature.

ColdFusion 8 introduced per application mappings. What this means is that each application on your server can have it's own mappings which are created at runtime (on each request). So why should you care? Well, have you ever written code like this:


<cfcomponent output="false">

<cffunction name="onApplicationStart"
returntype="boolean"
output="false">

    
<cfif CGI.SERVER_NAME eq "localhost">
<!--- dev environment, running from a folder in the web root --->
<cfset application.cfcpath = "myapp.">
<cfelse>
<!--- live environment, running from web root --->
<cfset application.cfcpath = "">
</cfif>

<!--- create singletons like beanfactories etc --->
<cfset application.mySingleton = CreateObject("component", application.cfcpath & "model.utility.mySingleton").init()>

<cfreturn true>
    
</cffunction>

</cfcomponent>

What the code above has some conditional code that checks what environment the script is running on and creates a application variable to set the path to the model folder. Everytime you want to create and instantiate a CFC anywhere in your application, you need to use the application.cfcpath variable (unless the CFC is in the same folder/package). If you try to just use:

CreateObject("component", "model.utility.mySingleton")

and you're not running from the webroot, then you'll get a nasty error along the lines of:


Could not find the ColdFusion Component or Interface model.utility.mySingleton
Ensure that the name is correct and that the component or interface exists.

With per-application mappings you can write it like this:


<cfcomponent output="false">

<!--- set up per application mappings --->
<cfset this.mappings = {}>
<cfset this.mappings["/model"] = GetDirectoryFromPath( GetCurrentTemplatePath() ) & "model">

<cffunction name="onApplicationStart"
returntype="boolean"
output="false">


<!--- create singletons like beanfactories etc --->
<cfset application.mySingleton = CreateObject("component", "model.utility.mySingleton").init()>

<cfreturn true>

</cffunction>

</cfcomponent>

ColdFusion now knows where your model folder is on the file system so you don't need to prefix your classpaths (the path to the CFC) anymore. Much nicer code!

 


5 comments

  1. Nice refresher. I'll just add that any conditional logic could still apply for dev/test/prod and just change where the mapping itself points to.

    Comment by todd sharp – February 15, 2010
  2. John, you're back! It's been awhile. ;-)

    Comment by Bob Silverberg – February 16, 2010
  3. @Todd, good point. Another thing you can do is move all your CFCs outside of the webroot which is kinda neat. You could even share the same CFCs across multiple projects without needing to access the CFIDE to define server mappings.

    @Bob, I didn't think anyone had noticed I was gone :)

    Comment by John Whish – February 16, 2010
  4. Great reminder. Just be aware that if you are using a Flex front end via AMF, per application mappings in CF 9 has an issue. The new AMF that ships with CF 9 only looks at the CF Admin registered mappings when looking up flex object aliases. Adobe has confirmed this issue and is working on a solution.

    Comment by phill.nacelli – February 16, 2010
  5. @Phill, that's a really good point and is something I've hit in the past (resulting in lots of swearing!) I didn't know that Adobe were working on a solution, let's hope it makes it into the CF9 updater.

    Comment by John Whish – February 17, 2010

Leave a comment

If you found this post useful, interesting or just plain wrong, let me know - I like feedback :)

Please note: If you haven't commented before, then your comments will be moderated before they are displayed.