Fun with Functions and CFCs III - Method Injection
posted under category: ColdFusion on December 12, 2007 at 12:00 am by Nathan
Using the code from the previous entry in this series, Fun with Functions and CFCs II, we can take the example further and inject a new method into a CFC:
<cfscript>
function methodToInject() {return "This method was Injected";}
myCFC.getVariables ().injectedMethod = methodToInject; // inject a method into CFC "variables" scope
myCFC.getVariables().this.injectedMethod = methodToInject; // also into public "this" scope
writeOutput( myCFC.getVariables ().privateMethod() ); // call private method from test.cfc
writeOutput( myCFC.injectedMethod() ); // call injected method
</cfscript>
We injected the method into both variables and this scopes so it would be available internally and externally.
Even more useful, you can replace existing functions:
<cfscript>
function h4x0r3d() {return "This method has been hacked!"} // create a 'hacked' message function
myCFC.getVariables().privateMethod = h4x0r3d; // replace privateMethod() with this function
</cfscript>
The next time anyone makes a call to privateMethod(), they will get "This method has been hacked!"
And deleting:
<cfscript>
structDelete(myCFC.getVariables(), "publicMethod"); // delete publicMethod from internal variables scope
structDelete(myCFC, "publicMethod"); // delete publicMethod from internal variables scope
</cfscript>
We had to delete it out of the public and private scopes (this and variables, respectively) - each scope had a pointer to the publicMethod() function.
Now, with a persistent component, like an application-scoped object, this can have long-lasting effects, but there could be many good uses for it, for example with an application lifecycle altering event such as a database crash, you could switch out calls to the database to instead return empty queries or a message.
Truthfully, it would probably be smarter to replace the entire component such as with a strategy pattern.