D365 Business Central Best Practices
Author: Yuran Shrestha
In this series of Best Practice blog for Dynamics 365 Business Central we define some of the best practices to follow when writing AL code. We recommend you follow these best practices when developing extensions in AL to ensure consistency and discoverability on file, object, and method naming, better readability of written code, as well as automated testing.
- Extension structure
An extension is fully contained in a single folder. This folder often contains multiple files, such as app.json and launch.json files, perhaps an image file representing the extension’s logo, various folders for source; “\src”, other resources; “\res”, and a test folder; “\test” folder. The extension need not follow a flat structure and depending on the amount of application files, additional folders can be used in the “src” or “test” folders to group objects on the basis of their functionality, which can help make maintain a large .al project easier.
2. File naming
File naming must start with the corresponding type and ID, followed by a dot for full objects or a dash for extensions. The name of the object is written only with characters [A-Za-z0-9] and dot al is used for the file type.
For file naming notation, you can follow the syntax for file naming as shown below:
Use the listed abbreviations for each type of object in the file naming:
Examples of file naming: The table below illustrates how the file naming should look.
|Object name||File name|
|codeunit 1000 “Job Calculate WIP”||Cod1000.JobCalculateWIP.al|
|page 21 “Customer Card”||Pag21.CustomerCard.al|
|page 1234 “MyPag” extends “Customer Card”||Pag21-Ext1234.MyPag.al|
AL Language extension offers you the choice to automatically format their source code.
We recommend that you keep your AL code properly formatted as follows:
- Use all lowercase letters for reserved language keywords. But in-built methods and types are not included in this rule since they are written using Pascal case.
- Use four spaces for indentation.
- Curly brackets are always on a new line. For one property, put it on a single line
The following example illustrates these formatting rules.
page 123 PageName
TempCustomer: Record Customer temporary;
[EventSubscriber(ObjectType::Page, Page::”Item Card”, ‘OnAfterGetCurrRecordEvent‘, ”, false, false)]
local procedure OnOpenItemCard(var rec: Record Item)
OnRecord: Option ” “, Item, Contact;
In general, there is no restriction in line length, but lengthy lines can make the code unreadable. We recommend that you keep your code easily scannable and readable.
Object names are prefixed. They start with the feature/group name, followed by the logical name as in these two examples:
- Intrastat extension validation codeunit for Denmark
- codeunit 123 “IntrastatDK Validation”
The “MS – ” prefix is not required
The structure for all objects inside an .al code file,: needs to follow the sequence below:
- Object-specific constructs such as:
- Table fields
- Page layout
- Global variables
- Labels (old Text Constants)
- Global variables
Here, objects are referenced by their object name, and not by their ID.
Page.RunModal(Page::“Customer Card”, …)
Customer: Record Customer;
All variables remain unchanged when they are named. This means that they can be named using Pascal case, temporary variables have the Temp prefix, and objects must include the object name in the name.
TempCustomer: Record Customer temporary;
Vendor: Record Vendor;
To declare a method, follow the guidelines below:
- Include a space after a semicolon when declaring multiple arguments.
- Semicolons can be used at the end of the signature/method header. If you use a snippet, the semicolons are not automatically added.
- The methods are named as variables using Pascal case. Though, it is not a mandatory rule.
- Blank line between method declarations is a must. Similarly, if you format your code using the AL Formatter tool, the auto-formatter sets the blank line between procedures.
local procedure MyProcedure(Customer: Record Customer; Int: Integer)
local procedure MyProcedure2(Customer: Record Customer; Int: Integer)
Include one space after each command if you are passing multiple parameters when calling methods. Likewise, parentheses must be specified while making a method call or system call such as: Init (), Modify (), Insert () etc.
Type definition (colon)
When declaring a variable or a parameter, the name of that variable or parameter must be immediately followed by a colon, then a single space, and then the type of the variable/parameter as illustrated in the example below:
local procedure MyProcedure(a: Integer; b: Integer): Integer
In extension, the name of each new application object (table, page, code unit), must contain a prefix or suffix. This rule applies to all objects. The prefix/suffix must be defined at the control/field/action/group level when you modify a core Dynamics 365 object using a Table Extension or Page Extension.
You can declare your objects with a prefix as shown in the example.
table 70000000 MyPrefix Salesperson
page 70000000 MyPrefix Salesperson
codeunit 70000000 MyPrefix Salesperson
There are two good reasons to proactively use a prefix or suffix:
- App A and App B both use the same field name (for a native Dynamics 365 table) of FAB Salesperson Code. The partner for App B has the prefix/suffix reserved. If a customer wants to install both apps he/she cannot due to collision of field name. App A will have to reserve a different unique prefix and submit an updated version of their app.
- Dynamics 365 developers want to use the name of Salesperson Code. App A which is published for months, already has that field name. Microsoft will need the app to prefix its field names by submitting the updated app version.
Have a look at some of the general rules below:
- The prefix/suffix needs to be of at least 3 characters
- Object/field name needs to either start or end with the prefix/suffix
- If a conflict arises, the one who registered the prefix/suffix always wins (applies only for marketplace extension)
- Set the prefix/suffix at the top object level for your own pages/tables/code units
- Set the prefix/suffix at the top object level for pages/tables in the base application of BC that you extend,
- Set the control/field/action level for pages/tables of BC in the base application that you extend,
- Use the AppSourceCop tool to find all missing prefixes and/or suffixes. Configuration options for this tool can be found here. The Rules section explains the different checks the cop will do. For prefix/suffix detection, refer to the Configuration section, which explains how to set prefix in the AppSourceCop.json file.
Examples of acceptable prefix/suffix
- “FAB Salesperson Code”
- “Salesperson Code FAB”
We will be writing more on the exciting features of Business Central in the upcoming posts. If you would like to find out how you can take advantage of the latest updates within your organisation, Contact us today for a no-obligation consultation on 01296 328 689. Or email us at firstname.lastname@example.org.