The Microsoft Dynamics AX 2012 extension framework – Part 1
Arthur Greef and Michael Gall.
Microsoft Dynamics AX 2012 includes a new extension framework that can be used to reduce coupling between application foundation frameworks and their extensions.
This is the first part in a series of blogs that describes the design of the extension framework and gives examples of where this framework is used in Microsoft Dynamics AX 2012.
A typical design pattern used to extend Microsoft Dynamics AX capability is found in the bill of material (BOM) consumption calculation design. There are four parts to the extension design. The first part of the design specifies a base enumeration for each of the calculation formulas.
Base enum BOMFormula Formula0 Formula1 ... |
The second part of the design specifies a base class and base class extensions.
AOT/Classes class BOMCalcConsumption{} class BOMCalcConsumption_Formula0 extends BOMCalcConsumption {} class BOMCalcConsumption_Formula1 extends BOMCalcConsumption {} … |
The third part of the design specifies a static factory method on the base class that uses the value of a base enumeration parameter to instantiate a derived class.
class BOMCalcConsumption { client server static BOMCalcConsumption construct( BOMFormula formula, BOMCalcData calcData) { switch (formula) { case BOMFormula::Formula0: return new BOMCalcConsump_Formula0(calcData); case BOMFormula::Formula1: return new BOMCalcConsump_Formula1(calcData); ... } return new BOMCalcConsump_Formula0(calcData); }} |
In the preceding design example, the base class is tightly coupled to derived classes and needs to be modified each time that a new derived class is added to the application. In addition, a new enumeration must be added to the base enumeration. A less tightly coupled extension design that uses a class attribute and a class factory is now possible and has been used for product configuration adaptor extensions.
The extension framework uses the class attribute framework and class factory framework that is also new to Microsoft Dynamics AX 2012. These two frameworks are used to decouple base and derived classes in two steps.
1. Create a class attribute method by extending the SysAttribute class.
The following example is taken from the product configuration code in the Product information management module.
class PcAdaptorExtensionAttribute extends SysAttribute{ PCName modelName; public void new(PCName _modelName) { super(); if (_modelName == '') { throw error(Error::missingParameter(this)); } modelName = _modelName; } public PCName parmModelName(PCName _modelName = modelName) { modelName = _modelName; return modelName; } } |
2. Use the preceding class attribute to add metadata to a derived class.
For example, add the following code to extend the PCAdaptor class so that a MyPCAdaptor object is created instead of a PCAdaptor object when processing a product configuration that is created from a product configuration model named “Computers”.
[PCAdaptorExtensionAttribute('Computers')] class MyPCAdaptor extends PCAdaptor { protected void new() { super(); } } |
You can test that this extension works by performing the following steps.
1. Open the Microsoft Dynamics AX development environment.
2. Add the MyPCAdaptor class to the Application Object Tree (AOT), and then compile the class.
3. Add a breakpoint in the PCAdaptorFactory.getAdaptorFromModelName method.
4. Open the Microsoft Dynamics AX client.
5. Click Product information management >Common >Product configuration models.
6. On the action pane, in the New group, click Product configuration model.
The New product configuration model dialog opens.
7. Enter “Computers” in the Name field.
8. Enter a name in the Root component section Name field, and then click OK.
The Constraint-based product configuration model details form opens.
9. Add an attribute to the root component in the Attributes section.
10. On the action pane, in the Run group, click Test.
11. Select a value for the attribute.
12. Click OK.
The Microsoft Dynamics AX debugger should launch at the breakpoint added in step 3 in the preceding step list.
As you step though the code you will see how the SysExtensionAppClassFactory is used to create an instance of the MyPCAdaptor class.
adaptor = SysExtensionAppClassFactory::getClassFromSysAttribute(classStr(PCAdaptor), extensionAttribute); |
The getClassFromSysAttribute method works by searching through the classes that are derived from the PCAdaptor class until it finds a class that has a PCAdaptorExtensionAttribute that returns a product model name that matches the name of the product configuration model being tested. In this case, the name “Computers”.
The benefits of using this new extension model are that the base and derived classes are decoupled, and it takes less code to extend the capability of the Microsoft Dynamics AX application.
Comments
- Anonymous
November 15, 2014
Hi.Thanks for the article. We are just now about to upgrade to 2012 and are looking for new design patterns to manage our customizations in a cleaner way. One question.Is this really intended to map to a "user configurable" value such as the model name field or was this example just to show that ANY property of the class can be used in the extension?I would think that enumerations are still the recommended data type when mapping extension attributes simply because they are developer controlled values. - Anonymous
February 05, 2015
The comment has been removed