Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Mastering Microsoft Dynamics 365 Business Central

You're reading from   Mastering Microsoft Dynamics 365 Business Central The complete guide for designing and integrating advanced Business Central solutions

Arrow left icon
Product type Paperback
Published in Mar 2024
Publisher Packt
ISBN-13 9781837630646
Length 684 pages
Edition 2nd Edition
Languages
Arrow right icon
Authors (2):
Arrow left icon
Stefano Demiliani Stefano Demiliani
Author Profile Icon Stefano Demiliani
Stefano Demiliani
Duilio Tacconi Duilio Tacconi
Author Profile Icon Duilio Tacconi
Duilio Tacconi
Arrow right icon
View More author details
Toc

Table of Contents (21) Chapters Close

Preface 1. Microsoft Dynamics 365 Business Central’s Online Momentum 2. Mastering a Modern Development Environment FREE CHAPTER 3. Extension Development Fundamentals 4. Developing a Customized Solution for Dynamics 365 Business Central 5. Writing Code for Extensibility 6. Advanced AL Development 7. Handling Files with Dynamics 365 Business Central 8. Report Development 9. Printing 10. Debugging 11. Telemetry 12. Coding for Performance 13. Dynamics 365 Business Central APIs 14. Extending Dynamics 365 Business Central with Azure Services 15. DevOps for Dynamics 365 Business Central 16. Dynamics 365 Business Central and Power Platform Integration 17. Useful and Proficient Tools for AL Developers 18. Creating Generative AI Solutions for Dynamics 365 Business Central 19. Other Books You May Enjoy
20. Index

Understanding the AL Language extension

AL is now a cross-platform language that is deployed through an extension for Visual Studio Code. This extension not only supports deployment on Windows OSs but is also supported for the macOS version of Visual Studio Code, and recently, it is also supported on Linux.

The free AL Language extension is available for download from the Visual Studio Code marketplace (https://marketplace.visualstudio.com/items?itemName=ms-dynamics-smb.al). This provides an optimized experience for Dynamics 365 Business Central extension development and includes all the support and tools that you need to build apps, including the debugger.

You might also want to install other extensions that add more languages (such as PowerShell), tools (such as Docker), or enhanced editing features to the AL Language extension. A list of the most useful marketplace extensions used by Dynamics 365 Business Central in combination with AL Language will be provided in Chapter 17, Useful and Proficient Tools for AL Developers.

AL Language

Created by the Dynamics 365 Business Central modern development team, AL Language is the official Visual Studio Code extension for developing apps for small, single-tenant personalization and complex add-on vertical solutions that are deployed through the online Dynamics 365 Business Central AppSource marketplace.

The AL Language extension can be deployed in two different ways:

  • Directly, as a downloadable package from the Visual Studio Code marketplace
  • Manually, as an installable package (a file with a .vsix extension)

The manual way is only used when a specific version for a specific implementation is needed.

To start directly with AL Language, download it from the marketplace by following these simple steps:

  1. Run Visual Studio Code.
  2. Click on the Extensions view bar.
  3. In the search field, type Dynamics 365 Business Central.
  4. Select AL Language extension for Microsoft Dynamics 365 Business Central.
  5. Click on Install, and when the installation finishes, reload Visual Studio Code as requested. It shows the following AL Language extension:

Figure 2.25: AL Language extension

By hovering over the extension, a more verbose pop-up pane should appear with more info:

Figure 2.26: AL Language extension description

The AL Language build number, also known as the development build, is shown close to the title. In the preceding screenshot, the AL Language development build (or runtime) version is 12.1.887908.

The development build is very important because new language features and enhancements are typically not backported to older builds, so they could be outdated and not compatible with the more recent Dynamics 365 Business Central platform updates.

AL developers should always select the latest AL Language development build to benefit from the latest enhancements and stability features.

Right after installing the AL Language extension from scratch, the AL Home page is displayed. This page contains tips for getting started with AL development and, most importantly, feeds from the Microsoft product group on what’s new, announcements, or development best practices. See below for what it might look like:

Figure 2.27: AL Home page

Unchecking Show at startup will turn off popping up the AL Home page every time you start a new instance of Visual Studio Code or reload Windows. It is possible to completely turn this off or simply have it shown only when there are updates in the feed section. We will see how to configure it later in this chapter. In any case, you could always run AL Home from the Command Palette (F1) by using the command AL: Home.

The AL Language development model relates to creating, editing, and organizing flat text files with the typical .al extension. In short, AL Language development is simply folder- and file-based.

It’s worth mentioning that the Visual Studio Code terminology calls a root folder a workspace. The AL Language root folder represents the source code container for an extension. Therefore, the AL Language root folder is also called the Visual Studio Code development workspace. Keep in mind that this is completely different from a code-workspace file.

When creating whatever kind of AL extension, the workspace consists of the following items:

  • A launch.json file
  • An app.json file
  • Symbol files
  • .al object files (such as table, page, report, and codeunit)
  • Complementary files (such as the extension logo in .bmp format, translation .xlf files, and so on)

We will analyze AL Language objects and complementary files in more depth in later chapters. We will focus now on the backbone of the app development: launch.json, app.json, and symbol files.

launch.json

This file is stored in the extension’s workspace in a subfolder called .vscode and mainly determines the specific parameter settings – a sort of connection string – for downloading and uploading AL Language commands.

The following table shows the download and upload AL commands:

Download commands

Upload commands

AL: Download symbols

AL: Publish (F5)

AL: Download source code (F7)

AL: Publish and open in the designer (F6)

AL: Publish without debugging (Ctrl + F5)

AL: Rapid application publish (Alt + F5)

AL: Rapid application publish without debugging (Ctrl + Alt + F5)

Table 2.1: AL commands for downloading and uploading

It is also used just to establish a connection and download symbols at will, as in the case of the AL: Debug without publishing (Ctrl + Shift + F5) command, or to launch a specific debugging feature such as, for example, AL: Open Events Recorder.

The launch.json file is a JSON object, and one of its elements is a JSON array that might have different JSON values, each representing a set of attributes targeting different deployments: on-premises or SaaS. Attributes could be mandatory or optional, depending on the target deployment.

The following table shows the launch.json attributes:

Attribute: Description

Deployment type

name: Shown also in the debugger window, this is used to identify the set of launch parameters. Default values: "Your own server" (on-premises), "Microsoft cloud sandbox" (SaaS).

All

type: Constant value: al.

All

request: Default value: "launch". For debugging purposes, it could also be "attach" (to a specific session) or "initializeSnapshot" (when initializing a snapshot debugger session). Both will be covered in detail in Chapter 10, Debugging.

All

startupObjectType: Object type to run after publishing: "Page", "Query", "Report", or "Table".

All

startupObjectId: Used together with StartupObjectType. Defines the object ID to run.

All

tenant: AAD tenant (SaaS) or tenant name (on-premises) to connect to extract symbols and/or publish the extension package.

All

environmentType: "OnPrem", "Production", or "Sandbox".

All

environmentName: Name of the environment to which to connect.

All

startupCompany: This is the company that should be accessed right after publishing.

All

breakOnError: Specifies whether the debugger should stop when an error occurs. It is also possible to exclude try functions ("ExcludeTry").

All

breakOnErrorWrite: Specifies whether the debugger should stop on record changes (insert, modify, and delete). It is also possible to exclude temporary records ("ExcludeTemporary").

All

schemaUpdateMode: Determines the data synchronization mode. Possible values are:

  • "Synchronize": This is the default value. If there is already data deployed for this extension, it will be preserved and not removed. The extension metadata will be synchronized with the existing one, if any.
  • "Recreate": Wipes out previous metadata (tables and table extensions, typically) and uses the new metadata from scratch.
  • "ForceSync": Forces the schema synchronization. This should be used with extreme caution since it might lead to data loss scenarios.

All

dependencyPublishingOption: This applies in complex scenarios where multiple dependent apps are loaded from the same root folder. Possible values are:

  • "Default": Enables rebuilding and publishing all dependent apps.
  • "Ignore": Does not apply dependency publishing. This option should be used quite carefully since it risks breaking existing interdependent apps.
  • "Strict": Publishing will fail if there are any installed extensions that have a dependency on the root folder.

All

server: Dynamics 365 Business Central Server URL.

On-premises

serverInstance: Dynamics 365 Business Central Server service name.

On-premises

authentication: "Windows", "UserPassword", or "AAD".

On-premises

primaryTenantDomain: This is mandatory only with AAD authentication for on-premises deployments. It is the URL of the AAD.

On-premises

port: Dynamics 365 Business Central development port number.

On-premises

applicationFamily: Used to develop an embedded extension for AppSource. This is a tag for Microsoft to determine the targeted upgrade operation if specific AppSource extensions have been deployed in the tenant.

AppSource

launchBrowser: Specifies whether to launch a browser when publishing extensions.

All

enableLongRunningSqlStatements: Enables the capability of displaying long-running T-SQL statements while debugging.

All

longRunningSqlStatementsThreshold: The minimum value to consider as a long-running statement for a SQL query. Default value: 500 msec.

All

numberOfSqlStatements: Sets the number of SQL statements to be shown while debugging. Default value: 10.

All

enableSqlInformationDebugger: Enables the capability of retrieving T-SQL query information.

All

disableHttpRequestTimeout: Used to avoid timeouts when debugging web service calls.

All

forceUpgrade: Forces codeunits to re-run upgrades.

All

usePublicUrlFromServer: If set to false, it will use the value specified in the server parameter instead of the one set server side as PublicWebBaseURL in the customsettings.config file.

On-premises

useSystemSessionForDeployment: To prevent debugging, installs and upgrades codeunits (since they will run in another session).

All

Table 2.2: launch.json attributes

If you have set up more than one value in the JSON array, when you upload or download AL Language commands, you will be prompted to choose one of the parameter set names defined in the JSON array. Below is an example of a launch.json file with multiple elements:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Docker Sandbox US 23.1",
            "request": "launch",
            "type": "al",
            "environmentType": "OnPrem",
            "server": "http://BC-23-1-US",
            "serverInstance": "BC",
            "authentication": "UserPassword",
            "startupObjectId": 22,
            "startupObjectType": "Page",
            "breakOnError": "All",
        },
        {
            "name": "PACKT Cloud Sandbox",
            "request": "launch",
            "type": "al",
            "environmentType": "Sandbox",
            "environmentName": "SandboxUS",
            "startupObjectId": 22,
            "startupObjectType": "Page",
            "launchBrowser": true,
        }
    ]
}

app.json

Typically stored in the extension workspace root folder, app.json represents the extension manifest, written in JSON. Inside the JSON file, there are parameters referencing base and system application dependencies, the application parameter, the platform property, and runtime definitions. These terms need to be well understood when developing for Dynamics 365 Business Central, so we will briefly go over them next.

Base/system application dependencies

With the October 2019 major release (version 15.x), Microsoft converted all legacy C/AL code into AL objects. Currently, the old application monolith has been split into two main extensions:

  • System application: With approximately 1,500 objects, it is growing release after release thanks to the open-source community contribution.
  • Base application: Depending on the localized version, it spans from 7,000 to 9,000 objects, approximately.

To be extended, these need to be referenced as dependencies in the app.json file, and their symbols pulled from an on-premises or an online sandbox through the AL: Download symbols AL Language command.

Defining dependencies to the system and base application is super simple: just set the "application" parameter with the value of the major (or major.minor) version that your extension is targeting like, for example, "application": "23.0.0.0". This will instruct Visual Studio Code, when downloading symbols, to check and request the system and base application version to have a value equal to or higher than the one specified in the parameter.

Application parameter and platform property

When pulled in the .alpackages folder, symbols are typically referenced through a version number in the major, minor, build, and revision notations, and this is shown in the name of the symbols that are downloaded (for example, Microsoft_System Application_23.0.36560.0 and Microsoft_Base Application_23.0.36626.36918).

The major version digit typically corresponds to the Dynamics 365 Business Central major update release. The 2023 Wave 2 release update is major version 23. The 2024 Wave 1 update release will be major version 24, and so on.

The minor version typically corresponds to minor updates. The November 2023 Update 1 is minor version 23.1, the December 2023 Update 2 will be minor version 23.2, and so on.

The build number is a progressive number that is incremented by Microsoft as soon as there are changes committed to the branch that are related to feature enhancements or bug fixing.

When developing an extension, you must be aware of what system and application object level is needed as a minimum requirement, as defined in the application parameter of the app.json file.

When targeting a platform for development, you must be aware of the minimum requirements held by files, AL Language statements, and APIs in order to use their features, properties, and functions. If the minimum requirements are not met, these files, statements, and APIs could be exposed to avoid unpredictable behaviors from the application. To help with this, the platform property represents the results of the final compilation of the Dynamics 365 Business Central platform components (client, server, web server, and so on). This property is shown with the same notation as the application.

The application parameter and platform property typically have a different value, since platform code changes and application code changes follow different compilation paths and are merged in the end, right before performing classic and regression tests.

Runtime

Runtime represents the results of the final compilation of the Dynamics 365 Business Central AL Language extension file.

The notation is simpler and consists of a major, minor, and build version. For example, the Spring 2018 update (or the April 2018 update) is named major version 1, and it increases every year. The current runtime version that targets the 2023 Wave 2 platform and application has version number 12. It is worth noting that the runtime version does not correspond with the application version, so it is important to use the right combination of application and runtime together.

When developing extensions, within the app.json file, you can define what runtime version the application is targeting. This enables or disables different sets of features that can or cannot be part of the target platform deployment, and the AL Language extension’s runtime will detect that. For example, by specifying "runtime": "12.0", we are targeting all modern development features included with the 2023 Wave 2 release and upward. The following table shows the main app.json attributes:

Attribute

Description

Id

Global Unique Identifier (GUID) of the extension.

Name

Extension name.

publisher

Publisher name.

version

Version of the extension package with major, minor, build, and revision.

Brief

Short description of the extension.

description

Long and verbose description of the extension.

privacyStatement

URL to the privacy statement.

EULA

URL to the license terms and conditions for the app.

Help

URL to app helpdesk support.

url

URL to the extension package’s home page.

Logo

Relative or full path to the app logo from the root directory of the extension.

dependencies

List of dependencies from other extensions.

screenshots

Relative or absolute path to app screenshots.

platform

Minimum platform version supported.

idRanges

Range of application object IDs or an array of object ID ranges.

resourceExposurePolicy

It substitutes the now obsolete showMyCode parameter and is used to granularly set the accessibility of the source code and symbols. It will be discussed later in this chapter.

Target

Default value: Cloud. Set this value to OnPrem if you need to target the extension to on-premises deployment. Be well aware that the Universal Code initiative will apply higher fees year over year if you choose to target on-premises deployments.

helpBaseUrl

URL for the extension’s online help.

contextSensitiveHelpUrl

URL for the context-sensitive help for an AppSource extension.

supportedLocales

Comma-separated list of the local languages supported by the extension.

features

Optional features that could be enabled by the compiler. It will be discussed later in this chapter. An example is TranslationFile.

runtime

Minimum runtime version targeted by the extension.

source

Optional. It might contain source DevOps information such as the URL address of the source repo and the Git commit ID that triggered the extension build.

build

Optional. Build DevOps info such as the agent’s name and the URL at which to find the resulting build.

Table 2.3: app.json attributes

The following is an example of a condensed app.json file:

{
  "id": "dd03d28e-4dfe-48d9-9520-c875595362b6",
  "name": "Packt Demo Extension",
  "publisher": "PACKT",
  "brief": "Customer Category, Gift Campaigns and Vendor Quality Management",
  "description": "Customer Category, Gift Campaigns and Vendor Quality Management",
  "version": "1.0.0.0",
  "privacyStatement": "",
  "EULA": "",
  "help": "",
  "url": "http://www.demiliani.com",
  "logo": "./Logo/ExtLogo.png",
  "dependencies": [],
  "screenshots": [],
  "platform": "1.0.0.0",
  "application": "23.0.0.0",
  "features": [
    "NoImplicitWith","TranslationFile"
  ],
  "idRanges": [
    {
      "from": 50100,
      "to": 50149
    }
  ],
  "contextSensitiveHelpUrl": "https://PacktDemoExtension.com/help/",
  "resourceExposurePolicy": {
    "allowDebugging": true,
    "allowDownloadingSource": true,
    "includeSourceInSymbolFile": true,
    "applyToDevExtension": false
  },
  "runtime": "12.0"
}

Two of the main app.json parameters need a deeper analysis: features and resourceExposurePolicy.

The features parameter currently admits specifying the following placeholders:

  • TranslationFile: Adding this parameter flag in features enables the generation of a directory called Translations in the extension folder and an .xlf translation file containing all the labels used in all extension objects. Translation files will be handled in deep detail in Chapter 4, Developing a Customized Solution for Dynamics 365 Business Central.
  • GenerateCaption: If TranslationFile is set, it will automatically generate translation placeholders for all objects that do not have a Caption or CaptionML property explicitly specified.
  • GenerateLockedTranslations: This will generate the appropriate elements for locked labels in the translation file when building the extension.
  • AllTranslationItems: This will generate translation placeholders for all possible object elements in the extension.
  • ExcludeGeneratedTranslations: This excludes the generated translation files from the extension.
  • NoImplicitWith: By adding this flag, you instruct the compiler to switch off the use of the With AL statement and all implicit field definitions (e.g., within pages, you should always reference Rec.<fieldname>).
  • NoPromotedActionProperties: This will not admit any old promoted property definition in the extension and will switch on the new modern action reference syntax.
  • UseLegacyAnalyzerStrategy: This reverts to the previous – and quite expansive in terms of resources – code analysis where every change in the code will trigger code analysis within the entire project.

The resourceExposurePolicy parameter is an array of values and it is very important in defining if, when, and how to surface the code written in the extension. Currently, it supports the following Boolean elements:

  • allowDebugging: Capability of debugging the code. It will download locally the source code of the files needed to debug in .dal (non-editable) format.
  • allowDownloadingSource: Capability of switching on/off the download source button on the Extension Management page for that specific extension.
  • includeSourceInSymbolFile: Determines whether the source code should be included or not in the symbols package when publishing the extension through PowerShell cmdlets.
  • applyToDevExtension: By default, extensions published directly through Visual Studio Code (so-called dev extensions) always include the source code in the symbols package. Turning this flag on will perform the same action specified for includeSourceInSymbolFile and also for extensions that are going to be published with dev scope. It is worth noting that this will enable the ability to debug apps that have allowDownloadingSource turned off, if the app is deployed to a sandbox using Visual Studio Code.

This is not over. The app.json file is enriched with new parameters, release after release. Some of them could be considered of minor importance, considering a per-tenant extension development, but they could turn out to be vital for the clean development of ISV or AppSource extensions:

  • internalsVisibleTo: This is an array of apps that have been granted access to the objects that are defined with Access = Internal in the current extension.
  • propagateDependencies: This is used typically in large projects with a discrete dependency tree. If extension 1 depends on extension 2 and that depends on extension 3, by default, the primary extension will not be able to declare anything defined in extension 3. If extension 2 has this parameter set to true, then extension 1 will be able to see and declare methods defined in extension 3, without the need to explicitly add the extension manifest in the dependencies parameter of its app.json file.
  • applicationInsightsConnectionString: This is used to send telemetry logs in a specific ingestion endpoint. Please note that there is no need to specify any connection string in the Dynamics 365 Business Central Tenant Admin Center (TAC) to have these sent. It is used with AppSource apps by ISVs that could gather information from different deployment sources to improve the extension experience or for troubleshooting purposes.
  • keyVaultUrls: Within an AppSource app, it is typical to keep all the resource exposure policies as false and override them by specifying an Azure key vault that stores the AAD tenant ID(s) where some of these policies are different. Setting all resource exposure policies to false and implementing the override strategy is the highest level of private IP protection that could be reached for AppSource extensions.

    To learn more about Azure Key Vault, please read Dynamics 365 Business Central: Using Azure Key Vault for your secrets: https://demiliani.com/2020/10/06/dynamics-365-business-central-using-azure-key-vault-for-your-secrets/.

  • suppressWarnings: Code analyzers, which we will learn about later in this chapter, obey several error and warning rules identified by a rule ID. This parameter is a collection of warning rule IDs that should not be shown (skipped) in the Visual Studio Code Output window.
  • preprocessorSymbols: This is a list of names (symbols) used by preprocessor directives. Preprocessor elements or directives are used to set regions of code that could be expanded or collapsed, to suppress warnings in a more capillary way than suppressWarnings does and, overall, to instruct the compiler to include or exclude specified code blocks based on the existence of specific symbols. This is a very useful technique when working with obsolete objects or fields.

    To learn more about obsoleting code, please read Best Practices for Deprecation of AL Code: https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/devenv-deprecation-guidelines.

With this information, you should now be able to master both the launch.json and app.json extension configuration files and tweak them according to the runtime version. In the next section, we will introduce symbols and explain their vital importance in extension development.

Understanding symbols

Like in many other languages, symbols represent references to a collection of standard objects, properties, and functions. They are a special extension file themselves with the typical .app naming convention and are used to maintain object reference consistency while compiling, and they also populate valid IntelliSense entries.

With Dynamics 365 Business Central, symbols are already loaded inside the application database, and these can be grouped into two classes:

  • System symbols: Symbols for system tables in the 2000000004 to 2000000199 ID range, and also virtual table definitions, plus some system codeunits. All these structures cannot be modified through extensions. Typically, these are downloaded from any environment as a System.app file and rarely are changed within a major version.
  • Extension symbols: All other symbols are typically generated when compiling (Ctrl + Shift + B) any extension and are part of the app package.

Whenever you extend an application, you always need to have the appropriate symbols downloaded and in place. You can achieve this in two ways:

  • Connect to an online sandbox environment, run the Command Palette (F1), and type and select AL: Download Symbols.
  • Copy the required symbols manually from another place (such as the product DVD, for on-premises deployment) and store them in the defined symbol storage directory.

If you have a multiuser environment with developers that are working on the same staging tenant, you might think of downloading symbols through the Command Palette once and then setting a common path for storing the symbols for all users. In this way, it is possible to avoid downloading the same set of symbols every time, thereby increasing development productivity.

The default symbol-storing path can be changed using one of the following shortcuts:

  • From the Menu bar, go to File (Alt + F) | Preferences (P) | Settings (S), and then select AL Language extension settings.
  • Use the settings shortcuts (Ctrl + ,) and then select AL Language extension settings.

The parameter to change is Package Cache Path, the default value of which is set to the relative path, ./.alpackages.

Alternatively, you could run the Command Palette (F1), type and select Preferences: Configure language-specific settings…, then choose AL. The settings.json file will open, and you can then add or change the values of the al.packageCachePath parameter. Later in this chapter, we will also discuss other AL Language configuration settings.

Together with the system application extension, base application extension, and system symbols, your extension might also depend on other custom or third-party extensions. These extensions, then, should emit symbols that you should be able to download from the application database when invoking AL: Download Symbols from the Command Palette.

To specify that your extension has a dependency on another extension(s), you must populate the dependencies parameter in the app.json file. This is what the app.json file parameter looks like for an extension that depends on another app:

  "dependencies": [
    {
      "id": "dd03d28e-4dfe-48d9-9520-c875595362b6",
      "name": "Packt Demo Extension",
      "publisher": "PACKT",
      "version": "1.0.0.0"
    }
  ],

If you have installed waldo’s CRS AL Language Extension (https://marketplace.visualstudio.com/items?itemName=waldo.crs-al-language-extension), you could type tdependencywaldo to enable the code snippet to easily edit each JSON array element for this parameter. This will make your coding faster and prevent syntax errors. We will discuss the standard and custom code snippet features in the last section of this chapter and more on productive extensions in Chapter 17, Useful Visual Studio Code Extensions for Dynamics 365 Business Central Developers.

The version parameter of the dependent extension(s) represents the lower bound for the compiler to accept the symbols. In other words, symbol versions of the dependent extension lower than the one reported are not considered valid for download or compile operations.

Inside symbols

Symbols are the result of a compression operation of several files that are used by the AL Language extension. To demonstrate what is under the hood, use a decompression tool (for example, 7-Zip) to extract their content after renaming the .app package with the .zip extension.

To give a practical example, the following tables show the standard symbol components (files and directories) for a standard base application extension:

Filename

Description

[Content_Types.xml]

Specifies the content of the package. For example: .xml, AL, .json, .rdlc files, and so on.

MediaIdListing.xml

Specifies the extension logo filename and its ID.

navigation.xml

Contains entries for the Role Explorer.

NavxManifest.xml

Reports the manifest for the standard symbol or extension. In other words, it is a translation into XML of the app.json file.

DocComments.xml

Contains all documentation comments for tables, fields, functions, and so on. Below is a simple snippet for an AL function:

<member name="M:.Line With Price.GetPriceType:Enum::Price Type">
   <summary>
   Returns the price type that was set by the SetLine() method:
   </summary>
   <returns>The price type</returns>
</member>

SymbolReference.json

Contains all references in JSON notation to AL objects. It could also be quite a big JSON file (for example, in a standard base application, it is 60+ MB). These JSON files are heavily used by the AL Language extension to maintain reference integrity while compiling/building the app package and to enable all IntelliSense-related features. Basically, it is structured as an array containing a list of valid AL object parameters, as shown in the following snippet:

"Tables": [],
"Codeunits": [],
"Pages": [],
"PageExtensions": [],

For each of these object elements, there are specified fields, properties, functions, and so on.

Table 2.4: Symbol components

Symbol JSON files cannot be hacked/changed to manually generate or modify a symbol file.

Next, let’s also have a look at what the various symbols directories do:

Directory name

Content description

entitlement

Contains an XML file that stores entitlement entries for every object.

layout

Report layouts.

logo

Extension logo.

ProfileSymbolReferences

Symbols for profiles and related page customizations.

Src

AL files. Their content is used typically to show the code while debugging.

Translations

Translation files in the XLF format.

Table 2.5: Symbol directiories

Symbols are the beating heart of the extension validation mechanism and, as shown in the previous tables, they also could carry out the code, depending on how resource exposure policies have been set up in the app.json file.

To deeply analyze AL symbols, the Microsoft AL Language extension provides a useful tool with a few functionalities to analyze symbols, AL Explorer (Ctrl + Shift + F12):

Figure 2.28: AL Explorer

This tool is currently divided into four self-explanatory tabs: OBJECTS, EVENTS, APIS, and EXTENSIBLE ENUMS. For each tab, a list of entities taken by symbols is provided and it is possible to search for names, IDs, and so on, group them by specific properties or namespaces, filter them by modules or sources, or simply choose the ones bookmarked.

There are also very useful extensions in the Visual Studio Code marketplace. The most used, with currently more than 160,000 downloads, is AZ AL Dev Tools/AL Code Outline by Andrzej Zwierzchowski (https://marketplace.visualstudio.com/items?itemName=andrzejzwierzchowski.al-code-outline). This extension is very easy to use and is super powerful for inspecting symbols and their content. More on this extension, and others, will be discussed in Chapter 17, Useful and Proficient Tools for AL Developers.

Once you have identified the entity that you were looking for, you could even perform some actions. For almost all of the entities listed in the tab, you could always click on the Source button and inspect the code, while for runnable objects you could select the entry and click the Run button. Within events, you could select the publisher that you were looking for and easily click on the Subscribe button, to automatically add the prototype of a subscriber to your clipboard:

Figure 2.29: Copying a subscriber prototype to your clipboard

You could then paste the content of the clipboard in your custom Codeunit object, without the need to type all the signature elements.

As with the AL Home page, it is possible to completely turn this page off so it doesn’t pop up and we will see how to configure it later in this chapter. In any case, you could always run the AL Explorer page from the Command Palette (F1) by using the command AL: Explorer or by using the Ctrl + Shift + F12 shortcut.

After learning about symbols and the tools to analyze them, we have completed an overview of the main items that are needed to build an app. Let us have a look now at AL Language extension configuration, and how to set it up to have a more productive development environment.

AL Language extension settings

Per-user and per-workspace settings can be easily shown through the shortcut Ctrl + , (comma). An intuitive menu will be displayed, and by selecting Extension | AL Language extension configuration, a set of configuration parameters is listed. The following screenshot shows the AL Language extension configuration parameters:

Figure 2.30: Extension configuration parameters

Basically, these configuration values are saved into a file called settings.json. The following lists describe the most common ones, ordered per parameter type.

Path parameters:

  • al.packageCachePath: It is possible to change the default value to a local folder or a shared folder for multi-developer environments. This represents the path where to store and look for symbols.
  • al.assemblyProbingPaths: This parameter is fundamental to compiling extensions when there are references to external assemblies. Its data type is a JSON array, so the developer has to specify a comma-separated list of paths where the assemblies should be stored at design time.
  • al.editorServicesPath: If service logging is enabled, it determines where to store the service and debugger logs.
  • al.algoSuggestedFolder: This defines where any new project folder should be created. It overrides the default creation path.

Compilation parameters:

  • al.compilationOptions: Used to specify whether a report layout should be generated or not when compiling, if it does not exist, whether to have a serialized or parallel build of the package, and finally, the polling to emit diagnostics. Within the compilation options, it is also possible to specify the folder where the compiler should place the resulting extension file (.app).

Browser parameters:

  • al.browser: Choose your preferred browser to launch your Dynamics 365 Business Central application from Visual Studio Code or leave it to use the system default. It is useful if you have multiple browsers installed.
  • al.incognito: Choose to start the browser in a normal session that stores existing credentials or use the private/incognito browsing mode.

Miscellaneous parameters:

  • al.enableCodeActions: Enables or disables code actions such as automatically converting multiple if statements to a CASE statement or kicking in spell check. By default, it is enabled. Code actions, as you might imagine, are quite expensive in terms of resource consumption.
  • al.enableScriptIntelliSense: Enables or disables the IntelliSense for JavaScript control add-in script files.
  • al.showHomeAtStartup: You could choose to let the AL Home page pop up Always, Never, or, preferably, WhenUpdated.
  • al.showExplorerAtStartup: You could choose to let the AL Explorer page pop up Always, Once, or Never.
  • al.inlayhints.functionReturnTypes.enabled: Inlay hints are additional information provided for the source code that are displayed inline. Inlay hints should be enabled by default, but you could set them to have a different behavior by changing the parameter editor.inlayHints.enabled from on to offUnlessPresseds or onUnlessPressed to have the information appear selectively, depending on whether the Ctrl + Alt keys are being pressed.
  • al.inlayhints.parameterNames.enabled: As above, but info is provided for every single parameter name in the signature.

By pressing Ctrl + Shift in any place inside the settings.json file and typing al, you might have noticed that it will show a few other AL Language configuration parameters. These are related to code analyzers, rule sets, log paths, performance profilers, and other features that will be addressed later on or in other chapters.

If you would like to learn more about every single parameter and how to streamline your configuration for the best performance, we recommend reading Optimize Visual Studio Code for AL Development: https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/devenv-optimize-visual-studio-code.

After exploring the core settings that are needed to develop an extension, let us have a quick look into a notable feature offered by Visual Studio Code and the AL Language extension to better develop clean solutions according to best practices and guidelines: code analyzers.

You have been reading a chapter from
Mastering Microsoft Dynamics 365 Business Central - Second Edition
Published in: Mar 2024
Publisher: Packt
ISBN-13: 9781837630646
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime