I want to add a method dynamically to a component in ax 2012, how can I do this through code? Is it possible?
Asked
Active
Viewed 2,563 times
0

Jan B. Kjeldsen
- 17,817
- 5
- 32
- 50

user3226663
- 137
- 3
- 17
-
Not sure what you mean by "component" or what you are actually trying to accomplish, but did you take a look at the event handling possibilities in AX 2012 (https://msdn.microsoft.com/en-us/library/gg839762.aspx)? – FH-Inway Apr 24 '15 at 08:32
-
Actually the component here refers to class or table or form or map. I need to add a method dynamically like public static str getTime(){ ret "time "; } – user3226663 Apr 24 '15 at 08:56
-
Component here refers to a Class or Map or Table or Form in the AOT, I need to check if the method named getTime() like public static str getTime(){ret "3/3/2015";} exists in the component if not found then create the above method in that component. for Eg: we have class in the AOT named ImageListAppl, i need to check whether method named getTime() exists or not, if not found then create getTime() method dynamically in that class. this is same for other components also like tables, maps,forms. – user3226663 Apr 24 '15 at 09:02
-
Take a look at class `ClassBuild`, this should give you some ideas. When I find the time, I will write up an answer with some example code. – FH-Inway Apr 24 '15 at 14:25
2 Answers
3
Here is a job I wrote that demonstrates a bunch of different ways of doing what you're wanting:
static void Job79(Args _args)
{
TreeNode treeNode = TreeNode::findNode(@'\Classes\Activities');
SysDictClass sysDictClass = new SysDictClass(treeNode.applObjectId());
FormRun formRun = new FormRun(new Args(formStr(AifAction)));
Form form = new Form(formStr(AifAction));
ClassBuild classBuild;
SysDictTable sysDictTable = new SysDictTable(tableNum(AccountSumMap)); // Maps are treated like tables
SysDictMethod sysDictMethod;
int i;
MemberFunction method;
str methodSource = 'public static str getTime()\n{\n\treturn "3/3/2015";\n}';
// Find if class has a method
if (sysDictClass.hasObjectMethod('delete'))
{
info("Found object method delete");
}
if (sysDictClass.hasStaticMethod('main'))
{
info("Found static method main");
}
// Find if form has a method
if (formHasMethod(formRun, 'init'))
{
info("Found form method 'init'");
}
if (form.AOTfindChild('methods').AOTfindChild('refreshGrid') != null)
{
info("Found 'refreshGrid' method on AifAction");
}
if (sysDictClass.hasStaticMethod('getTime') == false)
{
classBuild = new ClassBuild(sysDictClass.name());
treeNode = classBuild.addMethod('getTime', methodSource);
if (classBuild.classNode().AOTcompile())
{
classBuild.classNode().AOTsave();
info("Added method getTime, compiled, and saved");
}
else
{
info(strFmt("Unable to compile method 'getTime' with source code '%1', restoring class...", treeNode.AOTgetSource()));
// Delete the non-compiling method
if (treeNode)
treeNode.AOTdelete();
classBuild.classNode().AOTsave();
}
}
else
{
info("Method 'getTime' already exists");
}
if (sysDictTable.isMap())
{
if (sysDictTable.doesMethodExist('getTime') == false)
{
treeNode = sysDictTable.treeNode().AOTfindChild('methods').AOTadd('getTime');
method = sysDictTable.treeNode().AOTfindChild('methods').AOTfindChild('getTime');
method.AOTsave();
method.AOTsetSource(methodSource, true);
method.AOTsave();
if (sysDictTable.treeNode().AOTcompile())
{
sysDictTable.treeNode().AOTsave();
info(strFmt("Added 'getTime' to AccountSumMap"));
}
else
{
info(strFmt("Unable to compile method 'getTime' with source code '%1', restoring class...", treeNode.AOTgetSource()));
// Delete the non-compiling method
if (treeNode)
treeNode.AOTdelete();
sysDictTable.treeNode().AOTsave();
}
}
}
}

Alex Kwitny
- 11,211
- 2
- 49
- 71
1
private void findOrCreateTimeStamp(
SysVersionControlTmpItem _item)
{
str timeStamp;
UtilElements utilElement;
SysDictClass dictClass;
ClassBuild classBuild;
SysVersionControlTmpItem item = _item;
str methodName = "csGetVersion";
int time = timenow();
TreeNode treeNode = TreeNode::findNode(item.ItemPath);
utilElement = treeNode.utilElement();
timeStamp = date2Str(
today(),
321,
DateDay::Digits2,
DateSeparator::Slash,
DateMonth::Digits2,
DateSeparator::Slash,
DateYear::Digits4,
DateFlags::None);
timeStamp = timeStamp + "_" +
num2str0(time div 3600, 2, 0, 0, 0) + "_" +
num2Str0(time mod 3600 div 60, 2, 0, 0, 0) + "_" +
num2Str0(time mod 3600 mod 60, 2, 0, 0, 0);
if (utilElement.recordType == UtilElementType::Class)
{
dictClass = new SysDictClass(className2Id(utilElement.name));
classBuild = new ClassBuild(utilElement.name, true);
if (dictClass.hasStaticMethod(methodName))
{
//Override method here, since the method already exists in the component.
classBuild.overrideMethod(methodName,
@"public static str csGetVersion()" +
"{" +
"return '" + timeStamp + "';" +
"}");
}
else
{
//Make a new method here since it does'nt exist in the component.
classBuild.addMethod(methodName,
@"public static str csGetVersion()" +
"{" +
"return '" + timeStamp + "';" +
"}");
}
classBuild.classNode().AOTcompile();
}
}
The above method is created by referring to previous answer and other professionals. It validates if the method exists in the class first. If found it overrides else creates new method. For other elements like Tables, Forms and Maps we can implement in the similar way.

user3226663
- 137
- 3
- 17