Skip to main content
Known Participant
April 15, 2009
Question

Making a CFC available to another CFC

  • April 15, 2009
  • 5 replies
  • 5570 views

I have 2 cfcs...one of them contains some query functions that will need to be available to another cfc.

How do I make an object available to another CFC?

Do I create an init() function at the top and chain it to the CreateObject?

I've been developing in CF for about a year and half now and just now have started to realize the value of CFCs, having to learn some fundamentals.  I'm not even sure I asked my question right...haha

Thanks,

Paul Ferree

This topic has been closed for replies.

5 replies

Inspiring
May 7, 2009

Best way to do it for me would be to make cfc 2 inherits cfc1.  So every properties and methods of cfc1 are available in cfc2 using the super keyword

Example of cfc1

<cfcomponent>

     <cffunction name="myFunction" access="public" returntype="string">

          <cfreturn "hello from component 1"/>

     </cffunction>

</cfcomponent>

In cfc2

<cfcomponent extends="cfc1">

     <cffunction name="callCfc1Function">

          <cfset theString = super.myFunction()/>

      </cffunction>

</cfcomponent>

Hope it helps

Damien

Participant
April 23, 2009

I got a question from this theme about how to implement multy cfc infrastructure and maximize perfomance.

I have 1 cfc that has all my functions (~2000 lines) for one application. For the simplicity at the early stages of development I put them all in one cfc and now I can't find myself in it and also when I make changes to one function it take some time to compile so I could see the results. I want to separate functions by their specialty into several cfcs.

I create object in Application.cfm this way:

<cfset myObj = createObject(main.cfc)>

What is the right way to call functions contained by secondary cfcs from the main.cfc so I only have to wait until the changed cfc compiles?

thanks a bunch

ilssac
Inspiring
April 15, 2009

I beleive that Grump Joe gave you the likely answer as I understood your question.

You can invoke a componet in another compent exactly the same as invoking it an any other CFML code with any of the available methods, <cfinvoke...>, createObject(), <cfobject...>, etc.  In Object Orientated language this is know as compisiting, I.E. one object using another object as a member property.

You can also utilize OO inhertance concept with the "extends" property of the <cfcomponent...> tag.  I do not beleive that is the solution to the problem you stated, but it is a concept of which to be aware.

Known Participant
April 15, 2009

I know I can CreateObject inside a function within a CFC, but how do I instantiate it in a way where I can reference that object throughout the rest of the CFC without doing a CreateObject in each function it uses...I thought I had to initialize it first or something.

I don't think I understand the extend concept either...I tried it but it wasn't working.

Paul

Inspiring
April 15, 2009

Sorry. This one posted but did not include the files. Please disregard and see next post.

Inspiring
April 15, 2009

Another alternative is to use composition in your CFC. That is, you would create a property in your CFC that is the other CFC. You can then call that CFC via the property. There's nothing wrong (on any level) with taking GrumpyJoe's approach and calling cfinvoke or createObject. I just wanted to throw this out since you mentioned that you were just getting started with CFCs.

Following is some code to illustrate:

First, the component with the query functions. Let's say it's called (named) QueryCfc.cfc and that it lives in the same folder/directory as the second CFC (below).

<cfcomponent>

  <cffunction name="get" access="public" returntype="query">

    <cfquery name="myQry" datasource="dsn">

      select * from my_table

    </cfquery>

    <cfreturn myQry />

  </cffunction>

  <cffunction name="set" access="public" returntype="query">

    <cfargument name="val1" type="string" required="true" />

    <cfargument name="val2" type="string" required="true" />

    <cfquery name="myQry" datasource="dsn">

      insert into my_table( col1, col2 )

      values( '#arguments.val1#', '#arguments.val2#' )

    </cfquery>

    <cfreturn myQry />

  </cffunction>

</cfcomponent>

The other CFC, which will use the function in the above.

<cfcomponent>

  <!--- if the file, QueryCfc lived in another directory, you'd need to change the type attribute to reflect that path, using the dot notation, such as webroot.folder1.folder2.QueryCfc --->

  <cfproperty name="queryCFC" type="QueryCfc" default="" />

  <cfscript>

    queryCFC = createObject("component", "QueryCfc");

  </cfscript>

  <cffunction name="doSomething" access="public" returntype="void">

    <cfset myRecordSet = queryCFC.get() />

    <!--- do stuff with the record set --->

    <cfreturn />

  </cffunction>

  <cffunction name="doSomethingElse" access="public" returntype="void">

    <cfset queryCFC.set('value1','value2') />

    <!--- do other stuff --->

    <cfreturn />

  </cffunction>

</cfcomponent>

The second CFC is composed of (has) an instance of the first CFC. With composition, the first CFC (QueryCfc) is created one time, when the second CFC is instantiated, and then can be used throughout the CFC where needed.

Again, both approaches (among others still) will work but thought you might like to see an additional way to accomplish the same result with CFCs.

Good luck!

April 15, 2009

You could <cfinvoke> it into a variable inside the calling cfc and use it, check out the livedocs on <cfinvoke>, or as you suggest you could createobject() it as well.  Just like you call a .cfc in a .cfm file your .cfc files can call them the same way.