SBX - Search With Button

SBX - Forum Post Title

Reflection - querying method metadata

Dynamics 365 for Finance and Operations Forum

Vilmos Kintera asked a question on 2 Oct 2018 4:56 PM
My Badges

Question Status

Verified

Hi

We have an AX 2012 R3 modelstore that went through the upgrade to 8.0 and there are a whole bunch of overlayering. We are trying to use reflection to identify programmatically that which standard AX methods exist in a package that is customized by us.

I only have been able to pull such information on a class or table level, but have been unable to pull details on method content.

Let's have an example, we have changed \Classes\Application object by modifying the dbSynchronize, logInsert, logDelete, logUpdate methods, and added a couple of new methods on our own.

If I use the Metadata Search tool with the search string as per below, it does return all methods from the Application class incorrectly, because the object itself is marked as being in both ApplicationPlatform, and our custom JAD package as well:

type:"method" model:"ApplicationPlatform.JAD"

Here is the piece of code we currently have in a C# project. It can display that which packages does the parent table belong to, and we check the names of the methods within the table if it contains our prefix of JAD. However those will not reveal standard methods overlayered. How would we get those listed as well?

TreeNode is deprecated, the metadata providers do not have method-level inspection as far as I can tell, and DictMethod also does not reveal package information.

Any ideas please?

using System;
//using System.Collections.Generic;
using System.Linq;
//using System.Text;
//using System.Threading.Tasks;
//using System.IO;
using Microsoft.Dynamics.AX.Metadata.Storage;
using Microsoft.Dynamics.AX.Metadata.Providers;
using Microsoft.Dynamics.AX.Metadata.MetaModel;
using Microsoft.Dynamics.Framework.Tools.MetaModel.Core;

namespace WIK_ScanForExtensibility
{
    class Program
    {
        static void Main(string[] args)
        {
            var environment = Microsoft.Dynamics.ApplicationPlatform.Environment.EnvironmentFactory.GetApplicationEnvironment();
            var packagesLocalDirectory = environment.Aos.PackageDirectory;

            IMetadataProvider diskMetadataProvider = new MetadataProviderFactory().CreateDiskProvider(packagesLocalDirectory);
            
            var l = diskMetadataProvider.Tables.ListObjects("ApplicationPlatform");
            var le = l.GetEnumerator();

            while (le.MoveNext())
            {
                AxTable t = diskMetadataProvider.Tables.Read(le.Current);

                var mi = DesignMetaModelService.Instance.CurrentMetadataProvider.Tables.GetModelInfo(t.Name);
                Console.Write("Table " + t.Name + " models: ");
                for (int j = 0; mi != null && j < mi.Count; j++)
                {
                    var bla = mi.ElementAt<ModelInfo>(j);
                    Console.Write(bla.Name + " ");
                }
                Console.WriteLine();

                Microsoft.Dynamics.AX.Metadata.Core.Collections.IKeyedObjectCollection sen = t.Methods;
                for (int i = 0; sen != null && i < sen.Count; i++)
                {
                    Microsoft.Dynamics.AX.Metadata.MetaModel.AxMethod method = (Microsoft.Dynamics.AX.Metadata.MetaModel.AxMethod)sen.getObject(i);
                    if (method.Name.Contains("JAD"))
                    {
                        Console.WriteLine();
                        Console.WriteLine("\\Data Dictionary\\Tables\\" + t.Name + "\\Methods\\" + method.Name /*+ treeNode.AOTLayers().toString()*/);
                    }
                }
                //Console.Write(".");
            }
            Console.WriteLine();
            Console.WriteLine("------- Press any key -------");
            Console.ReadKey();
        }
    }
}
Reply
Joris de Gruyter responded on 2 Oct 2018 5:19 PM
My Badges
Verified Answer

Vilmos,

considering overlayering is in separate files in Delta folders, you could just go directly against the XMLs. This is effectively what the metadata providers do as well, and was assuming there's a way to do this with the metadata API. But barring that, the raw XMLs have the data.

Reply
Vilmos Kintera responded on 2 Oct 2018 5:28 PM
My Badges

When I open the Delta XML file for our ApplicationPlatform.JAD\AxClass\Delta\Application.XML, the VS UI does that already for us directly by showing it as if it would be the AOT, highlighting the conflicts and the automerged overlayering, so it has been coded somewhere.

It would be great if we could somehow use the same logic via reflection either by getting a list of the packages on a method, or at least a flag like isOverlayered.

I have tried pulling in a bunch of assemblies and searching for something useful in the object explorer without much luck, and decompiling the VS extension for D365 would be a pain.

If you could pull out something readily available or put this requirement in the pipeline, that would be great.

Manually inspecting a thousand methods is not optimal :) Our goal with this is to identify which methods are overlayered with a conlict, and then automagically inspect whether the code is at the beginning/end of the method (so it could be moved to an extension), or it might need a method hook for extensibility which we could send in as a support request.

Reply
Vilmos Kintera responded on 4 Oct 2018 5:26 PM
My Badges

We have been able to get it done using a different approach, with BaseX tool through XQuery/XParth for the Delta folder.

I'll make a post about it tomorrow for anyone interested!

Reply
Joris de Gruyter responded on 2 Oct 2018 5:19 PM
My Badges
Verified Answer

Vilmos,

considering overlayering is in separate files in Delta folders, you could just go directly against the XMLs. This is effectively what the metadata providers do as well, and was assuming there's a way to do this with the metadata API. But barring that, the raw XMLs have the data.

Reply

SBX - Two Col Forum

SBX - Migrated JS