Simple CFC dependencies in ColdFusion?

I've been trying to improve the modularity of a couple of applications I'm working on and one of the biggest problem areas I have is with dependencies.

For performance it can be useful to cache cfc's in the application scope - but if there are CFC dependencies it feels very wrong to reference a CFC cached in the application scope from inside the CFC.

Eg:

<cfcomponent name="User" output="false">
<cffunction name="getCompany" returntype="any" output="false" access="private">
   <cfset oObj = application.cfcCache.CompanyManager.getCompany(instance.companyID)>
   <cfreturn oObj>
</cffunction>
</cfcomponent>

Doing the above makes the code very fragile and dependent on the existance of the above application scope object.

The other alternative to this problem would be something like this:

<cfcomponent name="User" output="false">
<cffunction name="getCompany" returntype="any" output="false" access="private">
   <cfset var oObj = createObject("component","CompanyManager").getCompany(instance.companyID)>
   <cfreturn oObj>
</cffunction>
</cfcomponent>

This is less dependant on the runtime configuration, but it does have the memory and cpu overhead of creating a new object everytime this is run.

In order to get to the middle ground between these to options I've started playing around with a simple way to resolve dependencies based as well as provide caching of the objects.

The core of the solution is a base class that all the other classes you use extend. This has a getDependency function which handles dependency resolution and caching.

<cfcomponent name="LCBaseClass" output="false">
<cffunction name="getDependency" returntype="any" output="false" access="private">
   <cfargument name="class" type="string" required="true">
   <cfargument name="args" type="struct" required="false" default="#structNew()#">
   <cfset var oObj = "">
   <cfscript>
      //Todo - cache object here
      oObj = createObject("component",arguments.class);
   
      if(structCount(arguments.args)){
         oObj = oObj.init(argumentCollection=arguments.args);
      }
   </cfscript>
   <cfreturn oObj>
</cffunction>
</cfcomponent>

Using this code to handle a dependency would look like this:

<cfcomponent name="User" extends="LCBaseClass" output="false">
<cffunction name="getCompany" returntype="any" output="false" access="private">
   <cfset var oObj = getDependency("CompanyManager").getCompany(instance.companyID)>
   <cfreturn oObj>
</cffunction>
</cfcomponent>

The example version above doesn't handle the caching yet - but it could quite easily cache it within the object or to the application scope. The only hurdle I have with this is where to set this configuration option.

Any thoughts on this appreciated - good, bad or ugly?

Comments
You may want to take a look at some of Ray Camden's recent posts on Object Factories.
# Posted By todd sharp | 3/10/07 11:32 PM
Mark,
This is a great post and I think it will really help others understand the beginning struggles of objects depending on one another (yes there is more..sorry). Have you had a chance to look at ColdSpring yet? It will solve some problems you are having as far as injecting dependencies into ojbects. Let's say for example you create object a and both objects b & c need to have a reference of ojA for them to work correctly. ColdSpring handles all of this for you. I would encourage you to take a look! You also may want to take a look at Peter Bell's Lightwire which also helps. Other than that great post!
# Posted By Dan | 3/11/07 9:18 AM
Hi Todd,

Any particular posts - I had a browse through some of them.

Hi Dan,
Thanks for the feedback - I've had a little look at ColdSpring and may end up using it for this but I feel it had quite a lot of config. I'm trying make CFC's work a bit more like Java objects, rather than having to wire them up externally. Peter's Lightwire looks very promising (and simple).

Also, part of the reason doing this is for my own exploration of the object oriented programming and design patterns.

Cheers,
Mark
# Posted By Mark Lynch | 3/12/07 8:07 AM
BlogCFC was created by Raymond Camden. This blog is running version 5.1.004.