Wednesday, June 13, 2018

Accidental Code Extensions

Ok, I'll preface this by saying I'm very much aware that the standard X++ code in platform and application has this issue too. Thanks for letting me know :-) But as the saying goes: do as I say - not as I do...

With that out of the way... Going back in time, the 7.0 X++ language supported extension methods like C#. You create a new class with any name, but ending in _Extension. Then, you can add a new public static method, and the first parameter is the object you're extending.
So for example:

static class MyExtensions_Extension
{
    public static void foo(PurchTable _purchTable)
    {
    }

    public static void bar(SalesLineType _salesLineType)
    {
    }
}
This class adds extension method foo() to the PurchTable table and method bar() to the SalesLineType class. This feature is now less used due to the [ExtensionOf()] "augmentation" class paradigm where you can have instance method, add member variables, access protected members, etc. However, the original extension method feature still exists, and in fact many people accidentally use it!

The issue happens when adding both extension methods and event handlers in the same class. In theory this sounds great - you have all your extensions in one place. For example:

static class MyPurchTableExtensions_Extension
{
    public void foo(PurchTable _purchTable)
    {
    }

    [DataEventHandler(tableStr(PurchTable), DataEventType::Inserting)]
    public static void HandlePurchInserting(Common sender, DataEventArgs e)
    {
    }
}

This works as expected - a new method foo() is added to PurchTable, and you're handling the inserting event. However, the unintended consequence is that you are ALSO adding a new method HandlerPurchInserting(DataEventArgs e) on the Common object! The compiler does not discriminate the fact that you have a handler attribute on that method. All it sees is you're adding a static method in an _extension class, with one or more arguments.


So... How many methods have you accidentally added to Common, XppPrePostArgs, FormRun or FormControl? :-)

11 comments:

  1. 1. When using [ExtensionOf()] class is not static.
    2. 4th rule of old AX7 documentation extension methods is not fulfilled. Rule states: "The first parameter in every extension method is the type that the extension method extends. However, when the extension method is called, the caller must not pass in anything for the first parameter. Instead, the system automatically passes in the required object for the first parameter."

    ReplyDelete
    Replies
    1. The development of artificial intelligence (AI) has propelled more programming architects, information scientists, and different experts to investigate the plausibility of a vocation in machine learning. Notwithstanding, a few newcomers will in general spotlight a lot on hypothesis and insufficient on commonsense application. machine learning projects for final year In case you will succeed, you have to begin building machine learning projects in the near future.

      Projects assist you with improving your applied ML skills rapidly while allowing you to investigate an intriguing point. Furthermore, you can include projects into your portfolio, making it simpler to get a vocation, discover cool profession openings, and Final Year Project Centers in Chennai even arrange a more significant compensation.

      Data analytics is the study of dissecting crude data so as to make decisions about that data. Data analytics advances and procedures are generally utilized in business ventures to empower associations to settle on progressively Python Training in Chennai educated business choices. In the present worldwide commercial center, it isn't sufficient to assemble data and do the math; you should realize how to apply that data to genuine situations such that will affect conduct. In the program you will initially gain proficiency with the specialized skills, including R and Python dialects most usually utilized in data analytics programming and usage; Python Training in Chennai at that point center around the commonsense application, in view of genuine business issues in a scope of industry segments, for example, wellbeing, promoting and account.

      The Nodejs Projects Angular Training covers a wide range of topics including Components, Angular Directives, Angular Services, Pipes, security fundamentals, Routing, and Angular programmability. The new Angular TRaining will lay the foundation you need to specialise in Single Page Application developer. Angular Training

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Good post Joris,
    I believe adding the link below will be much easier with the post.
    https://docs.microsoft.com/en-us/dynamics365/unified-operations/dev-itpro/extensibility/add-method-table

    ReplyDelete
  4. Joris, thank you for this info. I'm still a little unclear of exactly which scenarios do or do not trigger this unintended consequence of extension methods on common objects when event handlers are intended.

    Does the use of the ExtensionOf attribute eliminate this issue, or will you still have the problem for any X++ class if the class is static and ends with "_Extension" regardless of if you use the ExtensionOf attribute or not?

    For example, would these have the same issue?
    Scenario 1: (not sure why this class is static instead of instance, but took this from an example in our current implementation)
    [ExtensionOf(tableStr(PurchLine))]
    public static class PurchLine_xxxx_Extension
    {
    [PreHandlerFor(tableStr(PurchLine), tableMethodStr(PurchLine, modifiedField))]
    public static void PurchLine_Pre_modifiedField(XppPrePostArgs args)
    {
    //will this create extension method on XppPrePostArgs type?
    }
    }

    Scenario 2:
    [ExtensionOf(classStr(Global))]
    final static class Global_xxxx_Extension
    {
    public static str xxCustomStrReplace(str _str, str _fromStr, str _toStr)
    {
    //The Global class is static, so I think the ExtensionOf need to be also, but does this add an extension method to the type str?
    }
    }

    ReplyDelete
  5. Maybe someone should update the training material for MB6-894, which states: "To create new methods on a table without customizing, you should use a table extension class. This class can contain event handler methods which are bound to table events and also can contain additive nonevent-based methods such as display methods or calculation methods."

    ReplyDelete
  6. ind accommodating client audits and survey evaluations for Vtech DECT 6.0 Expandable 2-Handset Cordless Phone System with Digital Answering Device and Caller ID (CS6229-2) at Amazon.com. Peruse genuine and unprejudiced item audits from ou go to website

    ReplyDelete
  7. Thanks for taking the time to discuss this, I feel strongly about it and love learning more on this topic. If possible, as you gain expertise, would you mind updating your blog with extra information? It is extremely helpful for me. zcodesystem discount

    ReplyDelete