Some Dynamics AX customization best practices are applicable irrespective of AOT element. These standards include X++ standards, naming conventions, label standards, and Help Text guidelines.
This section discusses some best practices related to the X++ language. Conformance to this standard results in improved execution time, ease in upgrading and further customization, efficient use of OOP concepts, better readability of code, etc. Some general principles are as follows:
- Variable or constant or parameter declarations should be as local as possible to utilize memory resources in an efficient way.
- Error conditions should be checked in the beginning so that minimum work is done for action and rollback of action. This will also hinder denial of service attacks. Denial of service attack is an attempt to stress the system with too many garbage requests so that an authorized user is not served.
- The parameters supplied as value must not be modified or manipulated as it may increase the chances of using wrong values somewhere else.
- Code should be written in a clean fashion, which means unused variables, methods, and classes should be removed from the code.
- The existing MorphX functions or functionality should be used as much as possible (unless other best practices stop you from doing so), rather than creating new ones as it will make upgrading easier.
- The user should not experience a run-time error. All possible cases should be foreseen and handled accordingly. If some unpredicted case appears during run time, it should show an error in the Infolog with a message to help the users on how to avoid the situation and what action can be taken to prevent it.
- The value of the this variable should not be changed.
- The reusability should be maximized. E.g. rather than repeating lines of code at different places, a single method can be written so that changes in the method can be reflected at all the places where this method is used.
- There should be only one successful return point (except in switch statements) so that object deletion, etc. can be ensured.
- A method should perform a single well-defined task and be named according to the task performed.
Text Constant Standards
All the text used in Dynamics AX is supposed to be in a label file irrespective of its use e.g. user interface or error or success message. The use of text constants can be classified into two broad categories i.e. user interface text and system-oriented text.
The text used in the user interface should follow the following best practices:
- Modify property values on the extended data types or base enums inthe application.
- Never create duplicate label files i.e. the same text (in the same language) but a different label file.
- New label files can be created when customizing the text, but it is always recommended to reuse the standard labels. However, it may offer a disadvantage—all the changes made to the SYS layer label files will be gone whenever an upgrade occurs. So the decision of customizing an existing label file or creating new label file should be taken carefully.
- User interface text (labels files) should be used in double quotes.
System-oriented text constants must be in single quotes.
The principle uses of exception handling include freeing system resources (e.g. memory through object deletion, closing database connection, etc.) and providing constructive information in the Infolog so that the user can prevent such erroneous conditions. The following are a few recommended best practices related to exception handling:
- A try or catch deadlock or retry loop should always be created around database transactions that can cause deadlocks.
- In the retry clause the values of transient variables should be set back to the values before try.
A few recommended best practices related to the if-else statement and switch statement are as follows:
- Always use positive logic e.g. write if (true) rather than if (! false).
- Prefer switch statement rather than multiple if-else statements.
- Always end a case with a break or return or throw statement unless a fall through mechanism is intentionally used. When a fall through mechanism is used a comment should be given like //fall through so that it is clear to every reader.
For readability of the code, code should be written in a proper layout. Some chief best practices for code layout are as follows:
- Remove commented code before shipping code.
- Follow indentation rules.
- Follow case rules for naming classes, methods, tables, etc.
Following are a few best practices for methods:
- Methods should be small and logical so that it can be easily overridden or over-layered.
- Methods should perform a single well defined task and from their name the task performed should be clear.
- For static class methods and table methods, qualified client, server, or client server should be used in such a way that calls to other tiers are minimized. For greater details refer to the Best Practices for Designing section in the Developer's Guide.
- To ensure trustworthiness, appropriate access levels (public, private, or protected) should be assigned.
- Methods should be named according to the Dynamics AX naming conventions; the reserved keywords such as is, check, validate, set, get, and find should be used as per the Dynamics AX way of using these standard methods or functions. All methods using such keywords must not have side effects e.g. no assignment in validate, check, get, or is methods.
- Parameter's names must start with an underscore (_) character besides following other generalized naming conventions.
Dates are sources of error due to variations in date presentation formats and in values due to differences in time zone. A few best practices for handling dates are as follows:
- Date fields must be stored or displayed in the date field only as IntelliMorph has the ability to display the date value in a format suitable for the user provided that the date format property is chosen as Auto and it is presented in a date control.
- The system date should not be considered as reliable information but in some cases (e.g. validation of information input by a user) system date should be read using the SystemDateGet() function instead of the today() function.
- Date conversion should be avoided as it will loose date properties and hence sometimes conversion may result in wrong information. For all user interface-related situations strFmt or date2Str should be used with a value of -1 for all formatting-related parameters. This will allow users to use this information in the format specified in regional settings. Care should also be taken that string variables storing converted date information are sufficiently long.
It is highly recommended that any user-interface text is defined using labels. This will ensure many advantages during translation. A few label file standards to ensure the true benefits of the label file system are as follows:
- The location of label files should be the most generalized one i.e. extended data type (EDT). In some cases an existing EDT cannot be used only because of the difference in label text. In such cases a new EDT should be created by extending the existing EDT. In such cases other alternatives may also be available (e.g. label change at the field) but the rule of thumb is to use the label at the most general place.
- The label files should not be duplicated i.e. two label files should not exist for the same text.
AOT Object Standards
The AOT object standards are specific to a particular AOT element. Broadly we can classify AOT elements as follows:
- Data Dictionary
- Extended data type
- Base Enum
- Feature keys
- Table collection
- Menu items
This is a group of AOT objects including the items mentioned in the previous section. The best practices for tables can further be divided into best practices for the fields, field groups, indexes, table relations, delete actions, and methods.
Extended Data Type
The EDT plays a great role as it is the basic entity of GUI elements. The following are a few basic best practices related to extended data types.
- All date and date format-related properties should be set to Auto.
- Help text should not be same as the label property. Help text is supposed to be more descriptive and should be able to explain why and/or how.
- An EDT name must be a real-world name, prefixed with module (if it belongs to one module only).
The following are a few basic best practices related to Base Enum:
- The Enum name should be an indication of either the few possible values or type of values. For example DiscountType, OpenClose, etc.
- Display length property should be set to auto so that in every language the full name can be displayed.
- Help and label properties must have some value. Help and label properties should not have the same value.
Many of the best practices for tables come under the scope of performance optimization, database design standards, etc. and hence those standards have been discussed elsewhere. Some of the standards not discussed are discussed here.
- The table name may consist of the following valuable information:
- Prefix: Module name such as Cust for Account Payable, Sales for Account Receivables
- Infix: Logical description of the content
- Post fix: Type of data e.g. Trans (for transactions), Jour (Journals), Line (table containing detailed information about a particular record in header table), Table (primary main tables), Group, Parameters, Setup, or module name to which the table belongs
- Label is a mandatory property and tables must be labelled using Label ID only. The text value of Label ID must be unique in all languages supported.
- If a table belongs to one of the four types Parameter, Group, Main, or WorksheetHeader, then it must have an associated form to maintain the table records. This form should have a name identical to its display menu item (used to start this form) and like the table name. formRef is the property of a table for the name of the associated form.
- Title Field 1 and Title Field 2 should be mentioned:
- TitleField1: The key field for the records in the table. This should be a descriptive title, if the key is information for the user.
- TitleField2: The description for the records in the table.
Most of the properties for the fields are inherited from extended data types; however, it is not mandatory to use some or all inherited values for such properties. Here are a few guidelines:
- Name: Should be like the corresponding EDT name but if named separately, it should be logical. The fields used as key should be postfixed as ID e.g. CustId, ItemId, etc.
- HelpText: This is a mandatory property and inherited from the corresponding EDT. Since Help Text needs to be customized as per the different uses ofthe same EDT, Help text can be modified at any field but the following arethe guidelines:
- The help text property should not be same as the label property.
- Label is also a mandatory property, which is inherited from EDT. If a value is set here, it should be different from the value on EDT.
- Every field that is either the primary key or one of the key mandatory properties must be set to Yes.
- Before considering memo or container type fields, it should be kept in mind that they add time to application and database fetch, they inhibit array fetching, and these types of fields cannot be used in where expressions.
The field group is a group of fields shown in the user interface. Dynamics AX has some standard groups (e.g. Identification, Administration, Address, Dimension, Setup, Misc, etc.), while other can be created. The fields that logically belong together can be placed in one field group while the Misc field group can be used to group fields that do not fit in any other field group. The dimension field group must have a single kind of field Dimension. The field groups should have the same kind of grouping at the database and form or reports to improve caching and hence the performance.
The database integrity is one of the key principles in Relational Database Management System (RDBMS). The delete action should be used on every relation between two tables. The following are key best practices for delete actions.
- Use a delete action on every relation between two tables.
- Use table delete actions instead of writing code to specify whether deletes are restricted or cascaded.
Dynamics AX has three types of delete actions; selection of one will solely depend upon the custom requirements.
The tables in Dynamics AX have several properties such as delete, validateDelete, etc. and hence Dynamics AX recommends that you should not write methods or X++ code to implement something that can be done just by setting property values.
Dynamics AX recommends using inbuilt table methods for those custom requirements that cannot be met with table properties settings. Some of the table methods are mandatory to implement e.g. find and exists methods.
The classes have a peculiarity that they may have both a back end (database) and front end (GUI). The front interface should be easy to use and at the same time as secure as possible. The implementation details of the class should always be hidden from the user and hence use of private or protected methods is recommended. The back-end methods are highly secure, standardized, and reliable and hence use of private or protected methods is recommended in prescribed design patterns. The design patterns depend upon the type of class. Classes can be categorized in the following categories:
- Real object
- Action class
- Supporting class
The following are a few common best practices related to declaration:
- Object member variables must only be used to hold the state of the object i.e. variables for which values should be kept between and outside instance method calls.
- Use of global variables must be minimized.
- Unused variables must be cleaned up; a tool available at Add-Ins | Best Practices | Check Variables can be used to know the unused variables.
- Constants used in more than one method in a class (or in subclass) should be declared during class declaration.
There is a rich set of best practices for classes and the Best Practices for Microsoft Dynamics AX Development released by Microsoft would be good read.
The forms are in the presentation tier in any three-tier architecture system. Most of them are related to look and feel or layout. Some other best practices for forms revolve around the following characteristics:
- Use of Intellimorph maximally
- No forced date or time format
- No forced layout such as fixed width for label, position control for GUI controls, etc.
- Use of label files for GUI text
- Forms having minimal coding
Avoid Coding on Forms
The basic concept of three-tier architecture is that forms should be used only for the presentation tier and hence no other code such as business logic should be there on forms. The code placed on forms also reduces their reusability and the ease of further customization; e.g. if you want to develop an enterprise portal, the code written on forms will have to be written again in classes or table methods, etc., which will make the implementation complex. Another example may be when you want to 'COM enable' your business logic; form code related to business logic will make your life almost impossible.
Any code (other than presentation logic) written on forms imposes limitation on performance as call between two different layers increase slowing the performance and hence code on forms should be avoided as much as possible. In cases where avoiding code on forms is not possible the guidelines summarized in the following table should be used for writing code on forms.
Place to Write Code
When code is related to whole form
When code is related to multiple data sources
Editor or Display methods (only those that are not related to any data source)
Data source-related Edit or Display methods
Code related only to the data source that cannot be effectively placed in a table method
When it is strictly related to the controls
Use of IntelliMorph Maximally
Due to a user's locale or preferred format a form may be presented in a different language and/or a different date, time, or currency format. Dynamics AX best practices recommend Auto as the value for the display properties related to the following:
- Number format (such as decimal operator, separator, etc.)
- Label size
- Form size
The rule of thumb is to keep the various properties as Auto or default value, which will help IntelliMorph to function maximally. For further details about best practices readers are recommended to go through the Developers Guide for Best Practices.
The peculiar fact about the reports is that they are output media where the external environment such as paper size, user's configuration about the locale or language, font size, etc. matters.
Dynamics AX recommends using 'Auto Design' to develop the report as these kinds of reports can change the layout according to external environmental variables. Another way to develop a report in Dynamics AX is 'Generated Design'; this type of design is recommended only when strict report layout is required. A few such examples may be regulatory reports, accounts reports, etc.
In this two part article we discussed various areas where quality could be improved by adopting best practices. We also discussed various best practices, theory behind best practices, and how to adopt these best practices, i.e. with practical tips.