When you develop new User Controls for Dynamics AX 2009 Enterprise Portal the Proxy Objects created by Dynamics AX make accessing AOT / X++ resources much easier from within your Visual Studio project.

However not all AOT resources are automatically available as Proxy Objects, but you need to exactly define what AOT elements you want to get Proxy Objects creates for. The MSDN Article Proxies explains what you need to do in detail.

But if you are creating a lot of new AOT elements, manually editing the Proxies list can get annoying. As everything about Proxies is actually available in the AOT, the manual task can get easily automated, e. g. by adding a new Menu Item to the Context Menu of the AOT.

 

First we need to create a new Class in the AOT. I have called the class SysAOTAddWebProxy in this example. The class declaration looks as follows:

class SysAOTAddWebProxy
{

    #AOT

    TreeNode m_proxyNode;
    TextBuffer m_proxyBuffer;
}

 

The default Construtor comes next. Here we load the existing Proxies list from the corresponding AOT node and store it in a TextBuffer object:

void new()
{
    //Get the Proxies node from the AOT
    m_proxyNode = infolog.findNode(#WebStaticFilesProxiesPath);

 

    //Get the Proxies list from the node
    m_proxyBuffer = new TextBuffer();
    m_proxyBuffer.setText(m_proxyNode.AOTgetSource());

    //For later comparison
    m_proxyBuffer.ignoreCase(true);
    m_proxyBuffer.regularExpressions(false);
}

 

In the Constructor the Proxies list is retrieved, in the SaveProxyList method it is saved back to the corresponding AOT node:

void SaveProxyList()
{
    //Save the changes back to the Proxies node in AOT
    m_proxyNode.AOTsetSource(m_proxyBuffer.getText());
    m_proxyNode.AOTsave();
}

 

The largest part is the adding of the selected Class in the AOT with its methods to the Proxies list. The AddProxyClass method is taking care about this. It is receiving the Class element to be added as parameter in form of a TreeNode object. The method checks if the Class is already part of the Proxies list and if not it is adding the class and all methods:

boolean AddProxyClass(TreeNode tn)
{
    boolean retVal = false;
    TreeNode tnChild;
    ;

    //Does the class already exist in the Proxies list?
    if(false == m_proxyBuffer.find(strFmt('/class:%1', tn.AOTname())))
    {
        //Add the class to the Proxies list
        m_proxyBuffer.appendText(strFmt('\n/class:%1\n', tn.AOTname()));

        //Get the methods of the class
        tnChild = tn.AOTfirstChild();

        while(tnChild)
        {
            //classDeclaraiton is no method, so skip but add the rest
            if(tnChild.AOTname() != 'classDeclaration')
                m_proxyBuffer.appendText(strFmt('    /method:%1.%2\n', tn.AOTname(), tnChild.AOTname()));

            //Next method
            tnChild = tnChild.AOTnextSibling();
        }

        m_proxyBuffer.appendText('\n');
        retVal = true;
    }

    return(retVal);
}

 

As the class should be called from the Context Menu we need to add a static Main method. The Main method is retrieving information for what AOT node the class was called, or in other words what AOT nodes should be added to the Proxies list:

static void Main(Args args)
{
    TreeNode contextNode;
    SysAOTAddWebProxy sysAOTAddWebProxy;
    ;

 

    //Where we called from the AOT Add-Ins context menu?
    if (SysContextMenu::startedFrom(args))
    {
        //Get the AOT node we were called for
        contextNode = args.parmObject().first();
        sysAOTAddWebProxy = new SysAOTAddWebProxy();

        while (contextNode)
        {
            //What node type were we called for?
            switch( contextNode.applObjectType() )
            {
                case UtilElementType::Class:
                    //Try to add the class to the Proxies list
                    if(true == sysAOTAddWebProxy.AddProxyClass(contextNode))
                        info(strFmt('The class %1 was added to the Proxies list!', contextNode.AOTname()));
                    else
                        warning(strFmt('The class %1 does already exist in the Proxies list!', contextNode.AOTname()));
                    break;

                default:
                    error(strFmt('The AOT element %1 cannot be added to the Proxies list!', contextNode.AOTName()));
                    break;
            }

            //If more nodes were selected in the AOT, get the next node
            contextNode = args.parmObject().next();
        }

        //Save changes back to the Proxies list
        sysAOTAddWebProxy.SaveProxyList();
    }
    else
        error('This class cannot be directly called!');
}

 

This is all about our class SysAOTAddWebProxy.

Now a new Action Menu Item needs to be created pointing to the class SysAOTAddWebProxy, and this Menu Item needs to be added to the existing SysContextMenu Menu. The MSDN Article Adding Items to the AOT Add-Ins Menu contains more detailed information about this step.

 

That’s it. When the class is in place and the Menu Item was added to the SysContextMenu Menu you should now be able to add a Class object selected in the AOT to the Proxies list by clicking with the right mouse button at the Class and selecting “Add-Ins > Your Menu Item text”.

If you want to extend the solution to work also with Tables and Enums you need to add methods similar to AddProxyClass and extend the switch block of the static Main method to call those for UtilElementType::Table and UtilElementType::Enum cases.

--author: Alexander Lachner
--editor: Alexander Lachner
--date: 16/12/2009