CFCs and the Base Component

So I totally dropped the ball during my CFC presentation at CFUNITED and forgot to mention one of the features of ColdFusion components. I didn’t mention it as I rarely have a use for it. If you look into your {cfinstall folder}\wwwroot\WEB-INF\cftags folder, you will find an empty tag called component.cfc. Whenever you create a CFC, ColdFusion will automatically make it extend this CFC.

So if you wanted all your CFCs to have a sayHello() method, you could just write it there. Hal Helms has a much better explanation here.

So as I said, I almost never use this file. For one - I typically don’t want to modify code in the cfusion folder. (Um, of course, that’s not exactly true. I’ve written mods to the exception handling and debugging templates, but that’s the Mirror Universe Ray for those Trek nerds out there.)

Last night though I had a need to quickly examine a bean CFC. My bean CFCs typically have a bunch of set/get methods, and I thought it would be nice if I could quickly call all the get() methods. I rewrote my base Component.cfc like so:

<cfcomponent>

<cffunction name=”dump” output=”true” access=”public” returnType=”void”> <cfset var md = getMetaData(this)> <cfset var x = ““> <cfset var result = structNew()> <cfset var value = ““>

&lt;cfloop index="x" from="1" to="#arrayLen(md.functions)#"&gt;
	&lt;cfif left(md.functions[x].name,3) is "get"&gt;
		&lt;cfinvoke method="#md.functions[x].name#" returnvariable="value"&gt;
		&lt;cfset result[md.functions[x].name] = value&gt;	
	&lt;/cfif&gt;
&lt;/cfloop&gt;

&lt;cfdump var="#result#"&gt;	 &lt;/cffunction&gt;

</cfcomponent> </code>

So what does this code do? It uses the meta data feature of CFCs to return the functions of the CFC itself. I loop over them, and if the method is getSomething, I simply invoke the method. Pay special attention to the cfinvoke tag:

<cfinvoke method="#md.functions[x].name#" returnvariable="value">

Notice how I didn’t use a component attribute? When you don’t do that, cfinvoke simply looks for a method locally. So, I call all the get methods, store the result in a struct, and then dump the struct. So now my beans have a dump method.

If I wanted I could have gotten more complex. Since I have the metadata, I could check the return type, and if it isn’t complex, call the method, no matter what the name. One day I need to package up all my little dangerous mods to the CF core files.

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate. He focuses on JavaScript, serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Comments