0% found this document useful (0 votes)
67 views71 pages

Best Practices

The document provides guidance on best practices for coding in Microsoft Dynamics AX. It discusses how to check code for best practice issues using the X++ compiler. It also describes how to disable specific best practice warnings or errors. The document then provides guidance in several areas including XML documentation, naming conventions, X++ coding practices, exceptions, databases, and formatting. It gives examples of good and bad code and provides checklists for various aspects of coding best practices.

Uploaded by

john mabatan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
67 views71 pages

Best Practices

The document provides guidance on best practices for coding in Microsoft Dynamics AX. It discusses how to check code for best practice issues using the X++ compiler. It also describes how to disable specific best practice warnings or errors. The document then provides guidance in several areas including XML documentation, naming conventions, X++ coding practices, exceptions, databases, and formatting. It gives examples of good and bad code and provides checklists for various aspects of coding best practices.

Uploaded by

john mabatan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 71

Best Practices

Dynamics AX 2012
Overview
• The X++ compiler checks the code for best practice issues.
• These issues can result in best practice errors, warnings, or
informational messages.
• These best practices apply to the following
• Programming in the standard application
• Certified solutions
Best Practices Checks
• Check your own code and application objects for compliance
with the best practices for Microsoft Dynamics AX.
• Select Tools > Options.
• Click the Development area, in the toolbar, click the Best
practices button.
• In the Warning level list, select the checks that you want to
perform.
• This will mean that best practices are checked when you
compile or check in an object.
• You can also check best practices for one or more nodes in the
Application Object Tree (AOT): right-click the node, and then
select Add-Ins > Check Best practices.
Best Practices Results
• Results are displayed in an Infolog, with the following severity
code:
• Information: Things that might be nice to know (shown in blue).
• Warnings: Things that you should strongly consider fixing (shown
in yellow).
• Errors: Things that should definitely be fixed (shown in red).
• If you double-click on an error message, this will open the
code editor.
Disable Individual Warnings and Errors

• You can stop a particular piece of code from causing a best


practice warning or error in two ways:
• By using a BP Deviation documented comment
• //BP Deviation documented
• By using the SysBPCheckIgnore macro
• You can stop a piece of code from causing a particular best practice
error or warning by adding the following line of code to
the SysBPCheckIgnoremacro:
• c+=[[# BPErrorCode ,@" AOTLocation "]];
• BPErrorCode is the error code for the warning/error as listed in
the SysBPCheck macro.
• AOTLocation is the location of the object causing the error, in the
Application Object Tree (AOT).
• For example, to disable an error message caused by renaming a class
to ProjTransCostForecast, you would write:
• c+=[[#BPErrorObjectNameConflict,@"\Classes\ProjTransCostForecast"]];
Generic AX Guidance
• The following sections provide Generic AX guidance to avoid best
practice violations. The sections provide guidance in the following
areas:
• Checklist
• XML Documentation
• Naming Conventions
• X++ Coding Best Practices
• Exception Guidance
• Database Guidelines
• Labels and text
• Data Integrity
• Intrinsic Functions
• Formatting Guidance
• Commenting
Checklist
• Development performed on proper layer.
• Development performed on proper model.
• Version control is used.
• Clean up your code as Diagnostic level 4 with BP parameters
• No objects should be left with their automatically generated
names (Class1, Method1, TabPage, Group1, ReportDesign1,
Field_1, Field1, etc.)
• Developer guidance document is followed.
XML Documentation Guidance
• XML documentation should provide information related to
usage. It should help a programmer decide if they want to use
the method.

• Add XML documentation with meaningful content.


• Use XML documentation to provide users and potential users
with the information they need.
• Do not use XML documentation to discuss implementation details
or other items not related to use.
• Do not add XML documentation for the sake of improving code
coverage.
XML Documentation Sample
Naming Conventions
• New objects names are prefixed as per guidelines in developer
document.
• Meaningful names are used for classes, methods, fields, etc.
object name should not be more than 40 Char.
• Object names are spelled correctly.
• Each path in the AOT is unique; nodes must not have identical
names.
• Do not begin a name with "aaa", or "CopyOf". Do not begin a
name with "DEL_" unless it is a table, extended data type or
enum, and it is needed for data upgrade purposes.
Naming Conventions
• All texts that appear in the user interface and code must be
defined by using a label. It must not be hard coded.
if(!this.CustGroup)
{
throw error("Please check the CustGroup");//@SYS123456
}

• Is the “DEL_” prefix used for deleted id based application


objects? And are they setup with the SysDeletedObjectxx
configuration key?
• Are the names of primitive types (str, date, int, real, boolean,
true, false etc.) given with a lowercase first letter?
Naming Conventions
• Use proper casing as defined in developer guidance.
Example: startBatchJob
• Use Pascal case naming for Application Object Tree (AOT)
elements.
Example: VendInvoiceJour
• Prefix parameter names in methods with an underscore (_).
Example: findVendByName(Name _name)
• Use upper case letters for acronyms that are two characters
long or less and Pascal casing with acronyms containing three
or more characters.
Example:
• VendAccountID
• CustAccountNum
Naming Guidance (For Method)
• check* - A Boolean method that checks a condition. If the condition
is not fulfilled, it must put a warning on the Infolog, and return false.
• find* - Finds a record in the table (where the method is declared).
The postfix is the name of the field which is used for accessing the
table, or a logical name for more fields.
• is* - A Boolean method that will check some condition. If the
condition is not fulfilled, it must return false. is* cannot change the
method. Information must not be sent to the Infolog.
• set* - Used for methods that set value(s) in the object. The name
must make it clear that the method also sets the state of some other
global members. set* methods should be void or Boolean, signaling
the result of the set.
• validate* - Same as check* but used more for transaction purpose
like inset delete
Naming Guidance Sample
X++ Coding Best Practices
• Declare variables as locally as possible
• Check the error conditions in the beginning; return/abort as early as
possible.
• Have only one successful return point in the code (typically, the last
statement), with the exception of switch cases, or when checking for
start conditions.
• Methods should be small, crisp and clear. The method should do a
single, well-defined task.
• Placement of curly brackets. Braces should be around every block of
statements, even if there is only one statement in the block.
• There should not be any dead/unreachable code sections.
• Only one statement per line.
• Never make assignments to the "this" variable.
• Clean up your code; delete unused variables, methods and classes. .
Bad Code Sample
Good Code Sample
X++ Coding Best Practices
• Break up complex expressions that are more than one line - make it
visually clear.
• Do not use parentheses around the case constants.
• Add one space between if, switch, for, while and the expressions
starting parentheses.
• Use methods on tables.
• Are the indirection methods error, warning, info and check Failed
used as opposed to calling infolog.add directly?
• Are ttsBegin/ttsCommit used in a clear and well balanced manner
• Reuse code. Avoid using the same lines of code in numerous places.
Consider moving them to a method instead.
• Reuse existing constants. Consider alternative ways of getting the
constant. Use existing intrinsic functions as maxInt, minInt,
funcName, maxDate etc...
• Use macros to define constants.
• Avoid dead code. (See Dead Code Examples.)
Dead Code Sample
Dead Code Sample
X++ Layout
• Is out-commented code removed?
• Indentation should be 4 characters .
• Are all starting and ending braces in the same level, on
separate, aligned with the command creating the block.
• To check the overall code layout compile the code with level 4
X++ Layout Sample
X++ Methods
• Are methods well-structured when it comes to good places for
overriding and over layering?
• Are method declarations exhaustive (client, server, public,
protected, private etc.)?
• Is underscore used to prefix parameter names?
• Is XML documentation cleared for method?
• Are all input values and return values well defined?
• Tagging should be correct.
Tagging Sample
Exceptions Guidance
• Exception handling done?
• Never use infolog.add directly. Use the indirection methods:
error, warning, info and checkFailed.
• Design your customizations to avoid deadlocks.
• Update conflicts handled?
• Do not throw an exception for an error condition that you
expect will need to be caught.
• Do not throw an exception for invalid assumption cases where
a Debug::assert is more appropriate.
• A rather useful statement in the X++ language is “retry”. Be
careful while using “retry”.
Exceptions Guidance
• Throw an exception to stop the currently executing X++ call
stack.
Exceptions Guidance
• Include a localized error message with all thrown exceptions.
• Use the info, warning, and error functions without a thrown
exception in cases where the executing X++ call stack should
not be stopped.
Exceptions Guidance
• Use throw with the static helpers on the Error class such as
Error::missingParameter and Error::wrongUseOfFunction for
errors targeted at developers.
Try Sample
Database Guidelines
• Include a try catch around all transactions that could result in
deadlock.
• Consider the clarity when deciding the number of return statements
in a method.
• Use throw instead of ttsAbort
• Avoid display methods where possible.
• Set Optimistic Concurrency Control ( OccEnabled ) to Yes for most
tables.
• Do not include user interaction inside a database transaction.
• Keep database transactions as short as possible.
• Run code on the Application Object Server (AOS) whenever possible.
• Use where clauses in select statements and in queries that align
with indexes.
Database Guidelines
• If method calls are used to test conditions, put the method calls
after the other conditions. If the other conditions fail, then you will
not incur the cost of running the method.
• Minimize the size of database transactions.
• Consider specifying a field list in select statements to increase
performance.
• Use firstonly where applicable to increase performance.
• Use aggregates in the selection criteria instead of having the code
do the aggregation. If aggregations are issued in the select
statement rather than in code, the processing is done at the
database server which is much more efficient.
• Use table joins instead of nested while loops. Whenever possible
use a join in the select statement rather than using a while loop and
then an inner while loop on the related table. This reduces the
amount of communication between the AOS and the database.
• Do not include any sort of user interaction in a transaction.
Bad Code Sample
Good Code Sample
Database Guidance
• Try to write X++
query instead of
SQL statement if
possible.
Database Guidance
• Apply Validations before passing any record as a parameter.
Ex: if you are finding any record and need to pass it as a
parameter, first check record exists if exists then pass it
• Try to write a code in table level instead of Form if possible
• Duplicate code should optimize
Sample code
Labels and Text Guidance
• Use labels for text that will appear on the user interface.
• Put labels in double quotes.
• Do not concatenate multiple labels together.
• Use single quotes for text that will not appear in the user
interface.
Labels and Text Sample
Labels and Text Sample
Data Integrity
• There are a number of concepts and features to consider
when adding, modifying, or deleting data to ensure that the
integrity and consistency of the data is maintained.
• Using table Delete Action elements.
• Using the for Update keyword correctly in select statements.
• Enabling transactions in your code.
• Avoiding deadlocks.
• Implementing Optimistic Concurrency Control (OCC).
Formatting Guidance
• Add one space between if, switch, for, while and the
expressions starting parentheses.
• Do not use parentheses around the case constants.
• Do not use parentheses around where expressions.
• An indentation is equivalent to four (4) characters, which
corresponds to one tab in the X++ editor. You must not start a
new line in columns 2, 3 or 4
• Do not omit braces. Braces are not optional because they
increase code readability and maintainability. They should be
included, even for single statement blocks.
• Place the opening brace at the beginning of the next line.
• Omit braces for switch statements. These braces can be
omitted because the case and break statements clearly
indicate the beginning and ending
Omit Braces Sample
Omit Braces Sample
Formatting Sample
Formatting Sample
Formatting Sample
Formatting Guidance
• Use a single space in the following cases:
• On either side of the assignment operator.
• After the comma between parameters.
• Between arguments
• Before flow control statements.
• Before and after binary operators.
• After the semicolon between the parts of for statement.
• Between a member name and opening parenthesis
• Before or after unary operators.
Single Space Sample
Commenting Code Guidance
• Do not use multi-line syntax /* … */ for comments. The single-
line syntax // … is preferred even when a comment spans
multiple lines.
• Do not place comments at the end of a line unless the
comment is very short. In most cases, comments should be
placed above the code.
• Remove TODO comments well in advance of a release.
Commenting Code Sample
Commenting
• Put comments on a separate line before the code they are
describing
• When creating a multiline comment, do not write on the first or the
last line of the comment(as shown in the following example).
• XML documentation feature should be used for commenting source
code. It is mandatory for public and static methods.
• All comments/expressions should be broken into multiple lines to
enhance readability.
• Complex Blocks of Code should be properly commented
• Avoid using clutter comments, such as an entire line of asterisks.
Use white space to separate comments from code.
• There should not be any comments that are not relevant to the
code.
• All comments should start with an upper case.
• Comments should be used to classify the modification type. Example
– commenting sys change, adding new lines ,etc.
• Reasons should be given if any base layer code is commented.
Dynamics AX Object Guidance
• The following sections provide Dynamics AX
Object guidance to avoid best practice violations.
The sections provide guidance in the following
areas :
• UX Guidelines for Client • Macros
• Tables and Maps • Forms
• Views • Reports
• Extended Data Types • Jobs
• Base Enums • Security
• Configuration and • Menus and Menu Items
Security Keys • Query Programming
• Classes • AIF Best Practice Checks
UX Guidelines for Client
• Primary list page – The primary list page is typically a list of master
or transaction data without a filter. In rare cases, a filter is needed
for the list page to be meaningful, for example, the Open Customer
Invoices or Pending PO Invoices list page. Primary list pages are
displayed in the first level of the Navigation Pane tree

• Secondary Detail page – The secondary detail page is a detail page


with a filter and is typically used for a specific activity or status. The
title of the page reflects the activity or status, for example, the
Orders details to Ship or Vendor Invoices details. Secondary detail
pages are displayed in the second level of the Navigation Pane tree..

• Action pane: The action pane is displayed at the top of each list
page. The action pane displays all the actions that are specific to the
list page, and each action can either relate to the selected record or
be independent of it.
Tables and Maps
• Metadata
• The table must have a 'Label' defined from a label file.
• The table must have a ‘HelpText’ defined from a label file.
• Title fields should be defined.
• The tables’ group property should be set properly according to its
purpose.
• The 'CacheLookup' field should be filled in.
• Table ‘FormRef” should be set if applicable.
• The 'table contents' should be set if this table contains base or
default data.
• Metadata Indexes
• Assign a unique index to each table.
• Add as few indexes as possible and maintain query performance.
• Strongly consider designating one of the indexes as the cluster index.
Tables and Maps
• Field Metadata
• All fields that are part of the primary key/ index should be
mandatory and should not be editable.
• All fields should extend from an extended data type and should
be part of at least one field group.
• The field must have a 'Label' defined from a label file.
• The field must have a 'HelpText' defined from a label file.
• Field Groups
• The ‘Auto Report’ field group must contain at least one field.
• All new field groups must have 'Label' defined from a label file.
• Additional field groups should be created that logically group like
fields that can be used on form and reports.
Tables and Maps
• Delete Actions
• To ensure referential integrity between tables (i.e. don't leave
orphaned records in a details table when the header is deleted) you
must set the delete action on the table.
• Methods
• Static ‘find’ and ‘exist’ methods should exist for the table’s primary
search key.
• A static find method should exist that fetch other related tables using
the foreign key contained in table.
• Property
• Table Group and Cache Lookup should be defined
• Relation should exists for each FK
• Should define the relation property as per the business process.
• You will get a best practices error if you create a relation on a table
but do not add any fields to it.
• Tmp related table should set as “in Memory”
Views
• Property
• The view must have a 'Label' defined from a label file.
• Title fields should be defined.
• The views’ group property should be set properly according to its
purpose.
• The view should be attached to a configuration and security key.
• View ‘FormRef” should be set if applicable.
• Note: This is critical for the “Go to main” functionality.
• Field Properties
• The field must have a 'Label' defined from a label file.
• The field must have a 'HelpText' defined from a label file.
• Field Groups
• The ‘Auto Report’ field group must contain at least one field.
• All new field groups must have 'Label' defined from a label file.
• Additional field groups should be created that logically group like
fields that can be used on form and reports.
Extended Data Types
• Use an extended data type wherever possible.
• Do not directly use the system data
types recID or tableID. Use the extended data
type RefRecId or an extended data type derived fromRefRecId.
• Property
• The EDT must have a 'Label' defined from a label file.
• The EDT must have a 'HelpText' defined from a label file.
• Configuration key should be defined.
• Do not try to modify the parents EDT property
Base Enums
• Property
• The Base Enum must have a 'Label' defined from a label file.
• The Base Enum must have a 'HelpText' defined from a label file.
• Configuration key should be defined.
• It should start as Zero value
Configuration and Security Keys
• Property
• The Configuration & Security Keys must have a 'Label' defined
from a label file.
• New modules Security Keys should be created in similar fashion
and construction as standard AX based on menu structure and
sections (i.e. Daily, Inquiries, Reports, etc.)
• Security keys are obsolete in Microsoft Dynamics AX 2012 and
only exist to use for reference during a code upgrade. There is
a new security framework, which is called role-based security.
Classes
• Methods
• All text referenced in the class should be defined from a label in a
label file, (i.e.: messages, “infolog” information, etc..). Text constants
should not be used.
• Use private class methods instead of local functions (local methods)
wherever possible. Local functions cannot be overridden,
overlayered, or reused.
• Check for good SQL syntax.
• Ensure that you are using proper class type construct.
• You must specify an access level for your method.
• Check for and remove unnecessary comments.
• Remove unused variables that are part of the modification layer,
• Dangling semicolon should not be used in methods.
• Property
• The run on property should be set appropriately based on its
functionality.
Macros
• Macro names should start with an uppercase letter.
• You must only use macros for declaring constants or libraries
of constants that should be available everywhere in the
application.
• The #localmacro directive is the best choice when you want to
substitute part or all of an X++ statement into several
locations in your code.
• For example, a recurring part of an SQL where clause can be
reused as a macro.
Forms
• Methods
• Avoid putting any code in the Active method.
• Try to implement the Max code logic in table or Class level instead of
Form methods
• Data Sources
• The name of the data source should be the same as the table name.
• Note: When the same table is used multiple times on a form then the
name should be reflective to the purpose of that table on the form.
• Design
• When you design forms, their properties should retain
their Auto or Default settings. This is the primary form-design rule.
• Caption must be defined from a label file.
• Form should have a title data source defined.
• Design list elements name should be meaningful.
Reports
• Use query based reports when possible.
• Use a precision design for all reports. An auto design is a good
start point to create a precision design for a report. An auto
design will not create medium or complex reports
• Avoid using RDP classes when the data for the report is in a
table and the report dataset can use the table
Jobs
• Jobs should not be used in production code.
Security
• New/Existing
• New Role
• ‘Label’ must be defined from a label file.
• ‘Description’ must be defined from a label file.
• It should tag with Privileges, Duties and TPF Table as per business
Rule
• Privileges
• ‘Label’ must be defined from a label file.
• ‘Description’ must be defined from a label file.
• It should tag with Entry Point with proper Access Level
• Duties
• ‘Label’ must be defined from a label file.
• ‘Description’ must be defined from a label file.
• It should tag with Privileges
Menus and Menu Items
• All runable elements you create must have a corresponding
menu item, with the same name as the element.
• Property
• ‘Label’ must be defined from a label file.
• ‘HelpText’ must be defined from a label file.
• Ensure proper use of the ‘Run On’ property.
• Object Type should be defined.
• Define the permission type if required.
Query Programming
• Are queries built in the tree where possible, instead of
building the queries from code?
• Are the queryValue(), SysQuery::value(), SysQuery::range() etc.
methods used when working with query ranges?
AIF Best Practice Checks
• Make sure the document class is prefixed with AxD
• Note: If the query is defined the AIF wizard will automatically take
care of this else when user creates a class manually always prefix
the class with AxD.
• All the fields in a table must have set and parm methods
accordingly.
• Note:the AxBusinessClass (i.e. Ax <Table Name>) should have the
set/parm methods accordingly If user has added a new field in
table then set/parm methods need to add accordingly.
BP Case Study
• Fix all BP errors
• Create BP Case study report for errors.
• Perform code review for Naming Convention , Formatting &
other BP guidelines. Add your comments into BP Case Study
Report.
THANKS

You might also like