AX 7 (“Microsoft Dynamics 365 for Operations”) offers a new API for getting metadata of AX elements such as tables, form extensions, models and so on. It’s very easy to use, therefore even if you’re very familiar with the old TreeNode API, you should definitely pay attention to this new one.

The best place to start is in the MetadataSupport class in Microsoft.Dynamics.Ax.Xpp namespace (yes, the whole API is in an external library; it’s not written in X++).

The class offers many static methods providing information about elements. Taking tables as an example, you can use:

  • TableNames() to get a list of names of all tables in Dynamics AX.
  • GetAllTables() to get details of all tables as objects.
  • GetTable() to get details of an individual table (based on its name or ID).

The MetadataSupport class also offers a few helper methods such as IsTableMapped() and ConvertAxUserTypeToBaseType().

Element details are represented by classes with names prefixed with Ax. For example, GetTable() returns an instance of AxTable class. (All these classes are defined in another assembly; the namespace is Microsoft.Dynamics.AX.Metadata.MetaModel).

These classes provide all details you may need. For tables, you can see properties, fields, indexes, methods and everything else.

AxTable members

Let me give you a full example that you can take and run in your environment. It iterates all controls in a given form and put their names to infolog.

using Microsoft.Dynamics.AX.Metadata.MetaModel;
class MetadataDemo
    public static void main(Args _args)
        AxForm form = Microsoft.Dynamics.Ax.Xpp.MetadataSupport::GetForm(formStr(SysUserSetup));
        new MetadataDemo().showControlNames(form.Design);
    private void showControlNames(IFormControlCollection _control)
        var controlEnumerator = _control.Controls.GetEnumerator();
        while (controlEnumerator.MoveNext())
            AxFormControl control = controlEnumerator.Current;
            if (control is IFormControlCollection)
                this.showControlNames(control as IFormControlCollection); // Recursion

There are a few things to notice:

  • It starts with using Microsoft.Dynamics.AX.Metadata.MetaModel, so we don’t have to repeat this namespace when referring to classes such as AxFormControl.
    I didn’t bother to do the same with Microsoft.Dynamics.Ax.Xpp, because I’m referring to it just once.
  • I use IFormControlCollection interface instead of concrete classes when I need to work with something containing child controls. This also me to use the same code for the Design node as well as for container controls such as tab pages, because they all implement this interface. Such interfaces are extremely useful for writing generic code and fortunately they’re used quite a lot in this framework.
  • Notice that AX 7 allows us to use property names directly (e.g. form.Design), so we don’t have to resort to the underlying accessor methods (e.g. form.get_Design()) as in previous versions . It makes programming easier and code nicer.
  • As a side note, notice the comment pointing out the recursive call. I tend to always do that, to make the use of reflection immediately obvious.

I truly enjoy working with this new metadata API – it’s nicely designed and easy to use. The only problem might be that you need to be a bit familiar with .NET Interop (= accessing .NET objects from X++), but even if you aren’t, you’ll quickly learn those few things you need.