Logo
HOW TO
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
 
 
Windows Server

Microsoft Dynamics Ax 2009 : RunBase Framework Extension (part 1) - Property Method Pattern, Pack-Unpack Pattern

4/10/2013 11:43:49 AM

Use the RunBase framework throughout Dynamics AX whenever you must execute a business transaction job. Extending the RunBase framework allows you to implement business operations that don’t have default support in the Dynamics AX application. The RunBase framework supplies many features, including dialog boxes, query windows, validation-before-execution windows, the progress bar, client/server optimization, pack-unpack with versioning, and optional scheduled batch execution at a given date and time.

1. Inheritance in the RunBase Framework

Classes that use the RunBase framework must inherit from either the RunBase class or the RunBaseBatch class. If the class extends RunBaseBatch, it can be enabled for scheduled execution in batch mode.

In a good inheritance model, each class has a public construction mechanism, unless the class is abstract. If the class doesn’t have to be initialized, use a static construct method. Because X++ doesn’t support method name overloading, you should use a static new method if the class must be initialized further upon instantiation. Static new methods have the following characteristics:

  • They are public and static.

  • Their names are prefixed with new.

  • They are named logically or with the arguments that they take. Examples include newInventTrans and newInventMovement.

  • They usually take nondefault parameters only.

  • They always return a valid object of the class type, instantiated and initialized, or throw an error.

Note

A class can have several new methods with different parameter profiles. The NumberSeq class is an example of a class with multiple new methods.


The default constructor (the new method) should be protected to force users of the class to instantiate and initialize it with the static construct or new method. If new has some extra initialization logic that is always executed, you should place it in a separate init method.

2. Property Method Pattern

To allow other business operations to run your new business operation, you might want to run it without presenting any dialog boxes to the user. If you decide not to use dialog boxes, you need an alternative to them to set the values of the necessary member variables of your business operation class.

In Dynamics AX classes, member variables are always protected. In other words, they can’t be accessed outside of the class; they can be accessed only from within objects of the class or its subclasses. To access member variables from outside the class, you must write accessor methods. The accessor methods can get, set, or both get and set member variable values. All accessor methods start with parm. In Dynamics AX, accessor methods are frequently referred to as parm methods.


The following is an example of what a method implementing the property method pattern could look like.

public NoYesId parmCreateServiceOrders(NoYesId _createServiceOrders =
createServiceOrders)
{
;
    createServiceOrders = _createServiceOrders;

    return createServiceOrders;
}


If you want the method to work only as a get method, change it to something such as this.

public NoYesId parmCreateServiceOrders()
{
;
    return createServiceOrders;
}


And if you want the method to work only as a set method, change it to this.

public void parmCreateServiceOrders(NoYesId _createServiceOrders =
createServiceOrders)
{
;
    createServiceOrders = _createServiceOrders;
}


When member variables contain huge amounts of data (such as large containers or memo fields), the technique in the following example is recommended. This technique determines whether the parameter is changed. The disadvantage of using this technique in all cases is the overhead of an additional method call.

public container parmCode(container _code = conNull())
{
;
    if (!prmIsDefault(_code)
    {
        code = _code;
    }

    return code;
}


Tip

From the X++ editor window, you can access a template script to help you create parm methods. Right-click the editor window, point to Scripts, point to Template, point to Method, and then click Parm. A dialog box appears in which you must enter the variable type and name of the member variable that you want the parm method to give access to. You can also access the script by pressing Shift+F10 in the editor window and then selecting Scripts.


3. Pack-Unpack Pattern

When you want to save the state of an object with the option to reinstantiate the same object later, you must use the pack-unpack pattern. The RunBase framework requires that you implement this pattern to switch the class between client and server (for client/server optimization) and to present the user with a dialog box that states the choices made at the last execution of the class. If your class extends the RunBaseBatch class, you also need to use the pack-unpack pattern for scheduled execution in batch mode.

The pattern consists of a pack method and an unpack method. These methods are used by the SysLastValue framework, which stores and retrieves user settings or usage data values that persist between processes.

Note

A reinstantiated object is not the same object as the saved object. It is a copy of the object with the same values as the packed and unpacked member variables.


pack and unpack Methods

The pack method must be able to read the state of the object and return it in a container. Reading the state of the object involves reading the values of the variables needed to hydrate and dehydrate the object. Variables used at execution time that are declared as member variables don’t have to be included in the pack method. The first entry in the container must be a version number that identifies the version of the saved structure. The following code is an example of the pack method.

container pack()
{
;
    return [#CurrentVersion, #CurrentList];
}


Macros must be defined in the class declaration. CurrentList is a macro defined in the ClassDeclaration holding a list of the member variables to pack. If the variables in the CurrentList macro are changed, the version number should also be changed to allow safe and versioned unpacking. The unpack method can support unpacking previous versions of the class, as shown in the following example.

class InventCostClosing extends RunBaseBatch
{

    #define.maxCommitCount(25)

    // Parameters

    TransDate                   transDate;
    InventAdjustmentSpec        specification;
    NoYes                       prodJournal;
    NoYes                       updateLedger;
    NoYes                       cancelRecalculation;
    NoYes                       runRecalculation;
    FreeTxt                     freeTxt;
    Integer                     maxIterations;
    CostAmount                  minTransferValue;
    InventAdjustmentType        adjustmentType;
    boolean                     collapseGroups;



    ...

    #DEFINE.CurrentVersion(4)
    #LOCALMACRO.CurrentList
        TransDate,
        Specification,
        ProdJournal,
        UpdateLedger,
        FreeTxt,
        MaxIterations,
        MinTransferValue,
        adjustmentType,
        cancelRecalculation,
        runRecalculation,
        collapseGroups
    #ENDMACRO

}
public boolean unpack(container packedClass)
{
    #LOCALMACRO.Version1List
        TransDate,
        Specification,
        ProdJournal,
        UpdateLedger,
        FreeTxt,
        MaxIterations,
        MinTransferValue,
        adjustmentType,
        del_minSettlePct,
        del_minSettleValue
    #ENDMACRO

    #LOCALMACRO.Version2List
        TransDate,
        Specification,
        ProdJournal,
        UpdateLedger,
        FreeTxt,
        MaxIterations,
        MinTransferValue,
        adjustmentType,
        del_minSettlePct,
        del_minSettleValue,
        cancelRecalculation,
        runRecalculation,
        collapseGroups
    #ENDMACRO

    Percent    del_minSettlePct;
    CostAmount del_minSettleValue;

    boolean         _ret;
    Integer         _version    = conpeek(packedClass,1);

    switch (_version)
    {
        case #CurrentVersion:
            [_version, #CurrentList] = packedClass;
            _ret = true;
            break;

        case 3:
            // List has not changed, just the prodJournal must now always be updated
            [_version, #CurrentList] = packedClass;
            prodJournal              = NoYes::Yes;
            updateLedger             = NoYes::Yes;
            _ret = true;
            break;
        case 2:
            [_version, #Version2List] = packedClass;
            prodJournal              = NoYes::Yes;
            updateLedger             = NoYes::Yes;
            _ret = true;
            break;

        case 1:
            [_version, #Version1List] = packedClass;
            cancelRecalculation       = NoYes::Yes;
            runRecalculation          = NoYes::No;
            _ret = true;
            break;

        default:
            _ret = false;
    }
    return _ret;
}

					  


If any member variable isn’t packable, the class can’t be packed and reinstantiated to the same state. If any of the members are other classes, records, cursors, or temporary tables, they must also be made packable. Other classes that don’t extend RunBase can implement the pack and unpack methods by implementing the SysPackable interface.

When the object is reinstantiated, it must be possible to call the unpack method, which reads the saved state and reapplies the values of the member variables. The unpack method can reapply the correct set of member variables according to the saved version number, as shown in this example.

public boolean unpack(container _packedClass)
{
    Version    version = conpeek(_packedClass, 1);
;
    switch (version)
    {
        case #CurrentVersion:
            [version, #CurrentList] = _packedClass;
            break;

        default:
            return false;
    }
    return true;
}


The unpack method returns a Boolean value that indicates whether the initialization succeeded.

As mentioned earlier in this section, the pack and unpack methods have three responsibilities:

  • Switching a RunBase-derived class between client and server.

  • Presenting the user with final choices made when the class was last executed.

  • Scheduling the execution of the class in batch mode.

In some scenarios, it is useful to execute specific logic depending on the context in which the pack or unpack method is called. You can use the isSwappingPrompt method on RunBase to detect whether the pack or unpack method is called in the context of switching between client and server. The isSwappingPrompt method returns true when called in this context. You can use the isInBatch method on RunBaseBatch to detect whether the unpack method is called in the context of executing the class in batch mode.

Other -----------------
- Nginx HTTP Server : Basic Nginx Configuration - Testing your server
- Nginx HTTP Server : Basic Nginx Configuration - A configuration for your profile
- Windows Server : Network Access Policy and Server and Domain Isolation (part 4) - Planning NAP DHCP Enforcement, Domain and Server Isolation
- Windows Server : Network Access Policy and Server and Domain Isolation (part 3) - Planning NAP VPN Enforcement, Planning NAP 802.1x Enforcement
- Windows Server : Network Access Policy and Server and Domain Isolation (part 2) - Planning NAP IPsec Enforcement
- Windows Server : Network Access Policy and Server and Domain Isolation (part 1) - Network Access Protection Overview
- Monitoring Windows Small Business Server 2011 : Using Performance Monitor
- Monitoring Windows Small Business Server 2011 : Using Event Viewer
- Windows Server 2008 : Promoting and Demoting a Domain Controller - Promoting a DC to an RODC with an Existing Account
- Windows Server 2008 : Promoting and Demoting a Domain Controller - Demoting a DC with dcpromo, Using dcpromo with an unattend File
 
 
REVIEW
- First look: Apple Watch

- 10 Amazing Tools You Should Be Using with Dropbox
 
VIDEO TUTORIAL
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
 
Popular tags
Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8 BlackBerry Android Ipad Iphone iOS
Popular keywords
HOW TO Swimlane in Visio Visio sort key Pen and Touch Creating groups in Windows Server Raid in Windows Server Exchange 2010 maintenance Exchange server mail enabled groups Debugging Tools Collaborating
Top 10
- Microsoft Excel : How to Use the VLookUp Function
- Fix and Tweak Graphics and Video (part 3) : How to Fix : My Screen Is Sluggish - Adjust Hardware Acceleration
- Fix and Tweak Graphics and Video (part 2) : How to Fix : Text on My Screen Is Too Small
- Fix and Tweak Graphics and Video (part 1) : How to Fix : Adjust the Resolution
- Windows Phone 8 Apps : Camera (part 4) - Adjusting Video Settings, Using the Video Light
- Windows Phone 8 Apps : Camera (part 3) - Using the Front Camera, Activating Video Mode
- Windows Phone 8 Apps : Camera (part 2) - Controlling the Camera’s Flash, Changing the Camera’s Behavior with Lenses
- Windows Phone 8 Apps : Camera (part 1) - Adjusting Photo Settings
- MDT's Client Wizard : Package Properties
- MDT's Client Wizard : Driver Properties
 
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
2015 Camaro