AX – D365FO – Access private variables from an extension class

This will not work from a pre-event handler because you are the wrong side of super so the variables don’t exist yet.Or to be more precise if this approach isn’t working – i.e. you can’t get/see the variable you are after the chances areit hasn’t been instantiated yet but this is not going to be the case with a post event.

using System.Reflection;
[ExtensionOf(classStr(VanillaClass))]
final class SomeFormVanillaClass_Extension
{
    [PostHandlerFor(classStr(VanillaClass), methodStr(VanillaClass, insertSomeTableRec))]
    public static void VanillaClass_Post_insertSomeTableRec(XppPrePostArgs args)
    {
        
        VanillaClass      vanillaClass= Args.getThis();
        MyVariable        myVariable; // same name as variable in vanilla class

        var bindFlags = BindingFlags::Instance | BindingFlags::NonPublic;
    
        var buffer = vanillaClass.GetType().GetField("myVariable",bindFlags);

        myVariable = buffer .GetValue(vanillaClass);

        // Do stuff - change a field value etc.

    }
}

For completeness here also is how to call this from within a COC method.

Chain of command does not give you access to Private variables.This should be a good thing but…. (favourite topic here :)) ….. As we all know AX was written with an overlay/layer paradigm in mind not object extensionsand the orginal developers did not make some variables private/public/protected when they should have anddidn’t create parm methods to expose them etc…and now we find MS actively making some variables private that were simply protected which to be honest is attrocious behaviour.considering that there will, 100%, be code out there that is referencing these previously protected variables.The upshot is we find ourselves, yet again, needing to resort to bad practice in order to get code migrated to the latest version withinthe time frames available.

using System.Reflection; // Don't forget this - case is important

[ExtensionOf(classStr(vanillaClass))]
final class vanillaClass_Extension
{
    // declare public version of base class private variables
    public query baseQueryLoc;
    public boolean baseVariableLoc; 

    // Your chain of command extended method
    public void baseMethod(str someParameter)
    {
        this.publiclyExposePrivates(); // We really shouldn't be doing this

        // do stuff

        this.pokePrivates(); // or this

        next baseMethod(someParameter)

        // do more stuff

    }

    // Crack open the base class and grab its privates - See I told you
    public void publiclyExposePrivates()
    {
        var bindFlags = BindingFlags::Instance | BindingFlags::NonPublic;

        var buffer = this.GetType().GetField("baseQuery",bindFlags);
 if (buffer)
        {
 baseQueryLoc = buffer.GetValue(this);
        }
        var buffer1 = this.GetType().GetField("baseVariable",bindFlags);
        if (buffer1)
        {
            baseVariableLoc = buffer1.GetValue(this);
        }
        
    }

    // Having fiddled with its privates put them back
    public void pokePrivates();
    {
        var bindFlags = BindingFlags::Instance | BindingFlags::NonPublic;

        var buffer = this.GetType().GetField("baseQuery",bindFlags);
        if (buffer)
        {
            buffer.SetValue(this,baseQueryLoc);
        }
        var buffer1 = this.GetType().GetField("baseVariable",bindFlags);
        if (buffer1)
        {
            buffer1.SetValue(this,baseVariableLoc);
        }        
    }

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...