AX7:Removing overlayered code from foundation models using eventhandlers
Updated on: 15/02/2017 11:33 PM IST
In my previous post i’ve explained removing customizations using inheritance from foundation classes . That approach was limited to instance methods.
If we want to remove customizations from a static method the approach explained in the previous post would not work, since we can’t override static methods in the derived classes we have to refactor it using eventhandlers.
i) If the method is static and has a return type.
static string mymethod() { //some code return "string"; }
We can refactor it using post event handler of the method
[PostHandlerFor(classStr(MyClass), staticMethodStr(MyClass, mymethod))] public static void MyClass_Post_mymethod(XppPrePostArgs args) { args.setReturnValue("string value"); }
We can modify the return value in post event handler
ii) If the method is static and has no return value
static void mymethod2(str _name, int _age) { //DB operations MyTable myTable; select forUpdate myTable where myTable.Name = _name; if(myTable) { ttsbegin; myTable.Age = _age; myTable.update(); ttscommit; } }
The most of the static void methods that i’ve encountered during my code upgrade had the code for some sort of DB operations. Writing a post event handler will perform the same DB operation twice and is not an option.
This approach is not limited to static methods with code for DB operations, it can be used anywhere. But you’ll have to find piece of code to skip the code execution. Because…
We can write a pre event handler, get the parameters from args, perform the business logic in the pre event handler itself and make the parameters in args null. So that the actual method would not execute.
[PreHandlerFor(classStr(MyClass), staticMethodStr(MyClass, mymethod2))] public static void MyClass_Pre_mymethod2(XppPrePostArgs args) { str _name = args.getArg('_name'); int _age = args.getArg('_age'); MyTable myTable; select forUpdate myTable where myTable.Name = _name; if(myTable) { ttsbegin; myTable.Age = _age; myTable.update(); ttscommit; } args.setArg('_name', ''); args.setArg('_age', ''); args.addArg('tmpName' _name); args.addArg('tmpAge', _age); }
After the pre event handler the actual buisness logic in the method would not execute as we have set the null parameters. I’m storing the actual parameters as temporary parameters. I’ll explain why.
When i first implemented this approach, i thought making parameters null would be enough. But it isn’t, we have to set the parameters back to avoid unnecessary errors. Use the post event handler for this purpose.
[PostHandlerFor(classStr(MyClass), staticMethodStr(MyClass, mymethod2))] public static void MyClass_Post_mymethod2(XppPrePostArgs args) { args.setArg('_name', args.getArg('tmpName')); args.setArg('_age', args.getArg('tmpAge')); }
I’ve set actual values back to parameters.
Same refactoring approach can be used in instance methods as well. Mainly, when there are multiple derived classes, using the approach explained in the previous post would not work.
This was originally posted here.
*This post is locked for comments