For example UserService.getbyEmail() is really just a special case of BaseService.getByUniqueAttribute() which can be fully described by a small amount of metadata. Same goes for a lot of the common methods we write (especially the CRUD methods including most transformations and validations).
While I’m prototyping this I thought it might be cool to write a “generic method” allowing you to call different methods which are described declaratively in the configuration files for your objects so instead of having to write a bunch of methods you can just set the metadata and it will automatically provide you with the methods at runtime. Obviously this is just for declaritive methods using base methods – there would be no benefit in this approach for “real” methods with actual business logic or other programming constructs within them.
I just wanted to prototype this up quickly, so I’ve just added a base “call()” method so you can call(MethodName,ArgumentCollection). If the method name exists in the object (if StructKeyExists), it runs it, if it exists in the metadata it uses the metadata to call the appropriate base method with the appropriate parameterizations, and if the method doesn’t exist, it flags the (fatal) error condition by setting an error variable, dumping it and aborting.
This is not a great implementation. The “call()” syntax is non-standard and non-ideal, but it allows me to play with the approach of handling and creating methods dynamically and if I like this approach (I will probably end up deciding to generate methods instead) I can always to look at what language features CF provides for doing this “properly” and to see if there is a way of dynamically specifying functions at runtime (other than using a concatenation or template to generate, publish and include scripts which is seems to be a rather crude way of having to go!).