Skip navigation
Currently Being Moderated

Instantiate a component object

Feb 15, 2012 7:45 AM

Hi! I'm not too clear with instantiating a component object and using cfinvoke to call the function.

To make it clear I'm going to use an easy example as follow:

Supposed I have a registration application where all it does was just getting user information, validate them and insert them into a table.

Since this functionality will be used repeatedly by many new users, I made it into a component.

 

So I will have:

MyComponent.cfc : 

<cfcomponent displayname="UserRegistration" output="false">

    <CFFUNCTION name="Init" access="public" returntype="any" output="false" hint="Returns an initialized component instance.">
            <cfreturn THIS />
    </CFFUNCTION>  

     

 

 

  <CFFUNCTION name="Validate_and_Store_User" hint="Store registration data" >
  <cfargument name="st_NewUser" type="Struct" required="True">

 

 

    There will be user validation and SQL Insert script in here

 

  </CFFUNCTION>

 

 


</cfcomponent>

 

 

The Calling page is: RegistrationPage.cfm:

I'm calling it this way:

1. Instantiate the component object:

    <cfset objRegistration = createObject('component', 'MyComponent') />

#

then call the UDF:

 

 

<CFINVOKE  component="#objRegistration#" method="Validate_and_Store_User" st_NewUser ="#st_NewUser#">

 

 

 

 

My question is:

When a new user is trying to register, first, the component object is instantiated and then the UDF is called

But when there are more new users registering at the same time, does it means the component object got instantiated over and over again instead of just once?

Looking at the code, CF will run <cfset objRegistration = createObject('component', 'MyComponent') /> everytime a user is registering and this mean an instant of that component is created, so every user will instantiate a component object? is this how it is supposed to work?

I'm just using a registration as an example. My core confusion is on whether or not an instant of component need to be created for each user.

Thanks!













 
Replies
  • Currently Being Moderated
    Feb 15, 2012 8:17 AM   in reply to GKiew

    Okay, I wouldn't bother using both cfinvoke in this case, there's no need. You're right, putting this in your registration page will result in a new copy of the cfc being created on every request. There are a few options.

     

    If you're going to use more than one method from the component, I'd create an instance first then call the methods:

     

    <cfset MyCFC = createObject("component", "MyComponent") />

    <cfset MyCFC.validateAndStoreUser(st_NewUser) />

    <cfset MyCFC.someOtherMethod() />

     

    If you're only calling one method, you can do it directly, destroying the CFC immediately after it's used:

     

    <cfset ReturnResult = createObject("component", "MyComponent").validateAndStoreUser(st_NewUser) />

     

    However a better way (if the cfc is basically "static") is to create it at the Application level. In your Application.cfc's onApplicationStart() method:

     

    <cfset application.MyCFC = createObject("component", "MyComponent") />

     

    Then in your code, reference the *one* instance of the CFC without having to create/destroy it every time, so more memory efficient:

     

    <cfset ReturnResult = application.MyCFC.validateAndStoreUser(st_NewUser) />

     

    If the component is just a bunch of methods, create it at the Application level. If it's a Class, then you need a createObject() for each one - i.e. if you had a Person.cfc with a name property, that'd be a createObject() for each one. If they're just static CFCs, one on the Application scope is the way to go.

     

    Very good explanation on your part by the way, nice to have someone ask a sensible, comprehensible and well thought-out question for a change.

     

    O.

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 16, 2012 12:23 AM   in reply to GKiew

    ColdFusion doesn't have the concept of Static classes, so if three people all access the same page, and in that page you do a createObject() then yes, you have three separate objects each with their own properties in their own block of memory. There is absolutely nothing linking them at all.

     

    The only scope CF has where you can share objects between users (sessions) is the Application scope; therefore if you did the onApplicationStart method I said about and referenced *that* in all three requests, they are all truly using the same object in the same lump of memory. Therefore:

     

    On the other hand, when I have 10 users doing registration at the approximately the same time then there will still be 10 instances created for each user, right?

    Correct, but badly worded - there will not be 10 instances created for each user, there will be ten instances created - one for each user.

     

    You can try this out for yourself; inside your CFC create a property called this.MyCounter, and set it to 1:

     

    <cfcomponent>

      <cfset this.MyCounter = 1 />

    ... methods etc

    </cfcomponent>

     

    If anywhere on your page you do this:

    <cfset obj = createObject("component", "MyComponent") />

    <cfset obj.MyCounter++ />

    <cfoutput>#obj.MyCounter#</cfoutput>

     

    ...then you'll only ever get "2" returned to the page, because each page request is creating a new instance. If however you did the Application-level method:

     

    <cfset application.MyCfc.MyCounter++ />

    <cfoutput>#application.MyCfc.MyCounter#</cfoutput>

     

    ...then you'll see it increasing with every page refresh until the application timeout is reached.

     

    As an aside, if you do have properties stored inside your CFC that's then stored in the Application scope, then remember the whole point is that it can be references by many different pages - all in different threads. You therefore need to start using CFLOCK, but that's a separate discussion. As long as your CFC just has static methods which take in arguments and return values, this isn't a concern.

     

    Hope that helps.

    O.

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 17, 2012 12:49 PM   in reply to Owain North

    Owain North wrote:

     

    The only scope CF has where you can share objects between users (sessions) is the Application scope; therefore if you did the onApplicationStart method I said about and referenced *that* in all three requests, they are all truly using the same object in the same lump of memory.

    However, they never share ownership of the object at the same time.

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points