The decision on where to make a change is based on many factors. These are to accomplish two goals: impact on future upgrades and reducing the number of changes to accomplish a task. These help keep the code maintainable, and when the code is handled by fewer changes, it is easier to read too. There may be other considerations, such as performance, that also need to be taken into account.
Both are accomplished by making the right modification in the correct place, and this should always be as "low" as possible. When making a change, we would rarely change standard code. Instead, we place a hook so that it calls our code.
The following list shows the preferred order and achieves both the goals:
We only make a change at a higher level if it is not possible to write the code lower or we wish only to affect the behavior at the current level. This can happen when we need information from another data source on a form. In this case, we have to place a change at the form's data source level, since a table instance (the current record) does not have access to the form's other data sources—they exist only in the scope of the form.
Many classes have levels of hierarchy, which can make it more difficult to determine where to make the change. The SalesLineType
class, which handles table events for SalesLine
, has several subclasses that handle specific types of sales order lines. The hierarchy is obvious in this case, as the classes are suffixed with each type of order line. When modifying the behavior here, we would modify the SalesLineType_Sales
if we only want to affect the behavior for a standard sales order, or SalesLineType
should the change need to affect all types of sales order lines. We will cover specific examples of this later in this chapter.
This hierarchy isn't always obvious, but AX provides some useful tools to help understand the hierarchy where objects are used. These are discussed next.
The Cross-reference data works with tables, classes, and types. A good example of how this affects day-to-day usage is when adding a table to a query in the advanced query editor. To see this in action, follow these steps:
This list is built using the cross-reference data built from the relations specified on the tables, and provides the user with a very powerful query tool. Cross reference affects developers too, and is used to help work out which objects use or are used by the current AOT element.
There are two perspectives, Used by
and Using
. First, we will use the cross references to see what uses a field. We will do this in a few steps to highlight some important issues, the first being to update the element's cross reference:
ConFMSVehicleTable
table, right-click on the VehicleGroupId
field.VehicleGroupId
again and go to Add-Ins | Cross-reference | Used by. This will show a form similar to what is shown in the following screenshot:Used by
list is complete, as this cross-reference update only processed the current table. We have to perform a full cross-reference update in order to ensure that this is complete. To include our classes in the cross reference, select the classes under our project's Classes node and go to Add-Ins | Cross-reference | Update.Used by
list for the VehicleGroupId
field again. The following is what you see:Because the AX code base is so large, the cross-reference data must be cached, otherwise looking up cross references would be too slow to be useful. In order for them to remain relevant, we will need to update the cross-reference data. This is done from the development environment's main menu by going to Tools | Cross reference | Periodic | Update.
In the Update Cross Reference form, check Update data model and press OK. The data model is important, as it updates the 1:n
and n:1
relations used by the query editor. If any elements have been removed, renamed, or refactored, you should also check the Delete and Update options.
This will take a number of hours to complete, so it should only be done under the following circumstances:
In other scenarios, as required, if the cross-reference data is out of date and the benefit of getting it up to date outweighs the delay
We can also configure the compiler to automatically build the cross references as it compiles. This is done from the Options window under Tools. Click on the Development tab and then on the Compiler button. This will slow down the compilation, and should be turned off for full application compilations. It is quicker to rebuild the cross-reference data once the compilation has finished.
We have two options on the Add-Ins | Cross-reference fly-out menu: Using and Using (Instant view).
The Using option will use the stored cross reference information, and is only available after an update. This shows the data in the same form as the Used by options, but from the perspective of what the element is using.
For more information on the cross-reference tool, see Cross-reference Tool [AX 2012], http://msdn.microsoft.com/en-us/library/aa626961.aspx.
The type hierarchy is a very useful feature when trying to understand how types (types, tables, and classes) relate.
Before we look at the browser, there is a useful tool when we want a quick look at the hierarchy as we move around the AOT. It is Type hierarchy context, from the Tools menu. This appears (by default) docked to the right of the IDE, showing the hierarchy to the base type of the selected AOT node.
An example for the VehicleId
field on the ConFMSVehicleTable
is as follows:
When an EDT is selected, such as ConFMSVehicleId
:
The more powerful type hierarchy browser is available from the Tools menu or the Add-Ins right-click menu—Type hierarchy browser. When opened from the Tools menu, it starts displaying just the base types, and you can navigate down the hierarchy. We will investigate the SalesFormLetter_Invoice
class. So, either locate this class in the AOT and select Add-Ins | Type hierarchy browser, or open it from the Tools menu and use the search box.
Although it is very useful to see the hierarchy in this form, one of the more interesting features is seeing which of the parent class's methods are overridden. The hierarchy is shown in this screenshot:
The graphic on the right-hand side displays this hierarchy, as shown in the following screenshot:
You can see from the preceding screenshot that the afterOperationBody
method is introduced in the FormLetterServiceController
class. It is overridden by SalesFormLetter
and also by SalesFormLetter_Invoice
.
18.216.47.169