Understanding The Different CFC Instantiation Behaviours

Author: Steven Neiland
Published:

Warning: This blog entry was written two or more years ago. Therefore, it may contain broken links, out-dated or misleading content, or information that is just plain wrong. Please read on with caution.

Recently I have been working on a ColdFusion application I inherited which only uses components in a non "Object Orientated" fashion. While I was refactoring the logic I noticed that anytime a component method called another method it used the "<cfinvoke" tag and that the component was explicitly named even if the method was in the same component as the calling method.

Does Naming The Component Change The Logic

This got me thinking. Does explicitly naming the component in the cfinvoke call change the behaviour of the actual logic? (This is ignoring when we explicitly create objects.) There are two ways of looking at this:

  1. By naming the component a new transient instance of the component is created which is separate to the calling component.
  2. Alternatively because we are calling a method in the same component, ColdFusion knows to use the existing component

Testing This

In order to figure which is the actual behaviour out I wrote this simple test consisting of a component and a index file.

<cfcomponent output="false">

<!--- Set a private variable that we will use for testing --->
<cfset variables.testvalue = 1>

<!--- Create an init function for when we test using a object --->      
<cffunction name="init">
<cfreturn this/>
</cffunction>
      
<!--- Run the test --->
<cffunction name="runtest" output="true">
<!--- First output the value of the test variable as a placemarker which should have a value of 1 --->
<cfoutput>First: #variables.testvalue#<br/></cfoutput>

<!--- Next call the getValue method to confirm that it also returns 1 the value of the test variable --->
<cfinvoke component="cfcinvoker" method="getValue" label="Component specified, no increment. Expected value = 1: Actual = ">
      
<!--- Increment the test variable by one --->      
<cfset variables.testvalue = variables.testvalue + 1>

<!--- Recall the getValue method with cfinvoke explicitly naming the component --->      
<cfinvoke component="cfcinvoker" method="getValue" label="Component specified, variable incremented. Expected value = 2: Actual = ">

<!--- Recall the getValue method with cfinvoke without naming the component --->
<cfinvoke method="getValue" label="Component not specified, variable incremented. Expected value = 2: Actual = ">
      
<!--- Finally close the testing by confirming that the test variable = 2 --->
<cfoutput>Last: #variables.testvalue#<br/></cfoutput>
</cffunction>
      
<cffunction name="getValue" output="true">
<cfargument name="label" default="GetValue">
<cfoutput>
#arguments.label# #variables.testvalue#<br/>
</cfoutput>
</cffunction>
</cfcomponent>
1 2

Reader Comments

  • Please keep comments on-topic.
  • Please do not post unrelated questions or large chunks of code.
  • Please do not engage in flaming/abusive behaviour.
  • Comments that contain advertisments or appear to be created for the purpose of link building, will not be published.

Archives Blog Listing