Fun with Functions and CFCs III - Method Injection
posted under category: ColdFusion on December 12, 2007 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.