With so many new AX 2012 R3 implementations and upgrades and the soon-to-be-released AX 7 (Rainier) around the corner I thought it is time to get back in business to publish interesting articles, now using a new home for hosting my blog:

http://www.daxrunbase.com/

It is always recommended to write best practice error-free code, however in some cases Microsoft forces our hands to fall back to hardcoded values. This is the case with today’s topic as well, when we would like to override values in a SysOperation Framework Data contract.

The SysOperationServiceController.getDataContractObject() method has an optional parameter, where they expect the value of ‘_dataContract’ in the example below. However we can choose to refrain from hardcoding and extract the value with Reflection.

For reusability it is recommended to place such code in the Global collection class, then just call it like below:

public static IdentifierName getMethodParameterName(
    Object  _object,
    str     _funcName
    )
{
    DictMethod                      dictMethod;
    
    dictMethod  = new DictMethod(
        UtilElementType::ClassInstanceMethod,
        classIdGet(_object),
        strContains(_funcName, '.') ? any2str(conPeek(str2con(_funcName, '.'), 2)) : _funcName);

    return dictMethod && dictMethod.parameterCnt() ? dictMethod.parameterName(1) : _funcName;
}

 

[
    SysEntryPointAttribute
]
public void process(MyDataContract _dataContract)
{
    SysOperationServiceController   controller;

    // New instance of the Operation service controller
    controller = new SysOperationServiceController(
        classStr(MyClass),
        methodStr(MyClass, myProcess),
        SysOperationExecutionMode::ScheduledBatch
        );

    // Hardcoded text value. Using '', identifierStr(_dataContract), or a macro is just masking the problem
    contract = controller.getDataContractObject("_dataContract");

    // Instead we can use the collection class
    contract = controller.getDataContractObject(
        // to get classId of current object, and first parameter name of current method
        Global::getMethodParameterName(this, funcName()));

    contract.parmValue(123);
    (...)