I've been playing more with CFC and method injection, and started writing up a CFC to handle it intelligently for me.
After some playing around, I thought it might be nice to document the things I have found about doing method injection, including some very interesting behaviour.
First things first - a UDF is actually it's own class in it's own right, completely seperate from the CFC defintion. It's more like the CFC is simply linked to the UDFs that it is told to, rather than it actually being a solid container. This explains what happens when you type:
and you get all that weird stuff like 'cfindex2ecfm1512334719$funcMYMETHOD@1b1dd12'. This is just the output of the toString() function on the UDF itself. It seems to be the generated class name.
So if you do some reflection on the UDF class (
udfName.getClass() works just fine), you find that there is a
getMetaData() function - so depending on your preference:
getMetaData(myUDF) works - and returns a struct with everything you could ever ask for:
- An array of parameters
This is rather useful if you want to maintain the name of aUDF from one place to another.
Now... method injection in and of itself is very simple:
myCFC["methodName"] = myUDF;
Presto, you have created a new public UDF on a CFC.
You can also do the same thing inside a CFC by either doing (but each will make it work differently):
this["methodName"] = myUDF;
variables["methodName"] = myUDF;
But some things to note:
If you add an access="public" or access="private" UDF directly to a CFC (method 1 or 2), the UDF will be PUBLIC.
BUT, if you add a UDF to the variables struct inside a UDF (method 3), regardless of whether or not it's an access="public" or "private" or "package", it will be a PRIVATE UDF. (How to get it to the variables scope, I will leave up to you ;o) )
The real clincher here however, is that if you add a access="package" UDF directly to a CFC (method 1 or 2), then it will only be accessible from the folder the CFC is in. So obviously there is some runtime checking there that determines if it is being called from inside its own package.
That is pretty much the basics of method injection - hope you find that helpful.