How to: Develop an Extension
Extensions v1.0 are no longer supported. The text in the article applies to extensions v1.0. For information about writing extensions in AL, see the table below.
|For information about||See|
|Getting started writing extensions using the AL Language.||Getting Started|
|Converting extensions.||Converting Extensions V1 to Extensions V2|
|Writing extension install code for when an extension is installed for the first time, or for when an uninstalled extension is reinstalled.||Writing Extension Install Code|
|Making a newer version of an extension available.||Upgrading Extensions V2|
|Publishing, synchronizing, and installing the extension on the tenant.||Publishing and Installing an Extension v2.0|
You can build extension packages that add functionality to a Dynamics NAV deployment. Unlike the familiar development and deployment of Dynamics NAV functionality, building an extension relies on the exported version of an application to .TXT files. You can export the application from the development environment, use the development environment commands, or use the Windows PowerShell cmdlet that is available in the Microsoft Dynamics NAV Development Shell,
We recommend that you create a folder structure that can be leveraged by the cmdlets that you use when you build the extension package. That structure should contain folders for the ORIGINAL object files, MODIFIED object files, and DELTA files. These names match those used as parameters in the application merge utilities. For more information, see Comparing and Merging Application Object Source Files. In addition, you may want to create additional folders for any .NET add-ins, language files, or data files that you are going to include in the package.
To create an extension
Establish the BASE as TXT files.
The foundation for your extension is the exported .txt files of the objects you are modifying. You can export just the objects that you want to modify, or you can export the entire Dynamics NAV application. In the Microsoft Dynamics NAV Development Shell, the
Export-NAVApplicationObjectLanguagecmdlet can automate this process or you can use the export functionality in the development environment. The following example uses this cmdlet to export objects to establish the base for the planned modifications.
Export-NAVApplicationObject -Path ORIGINAL -DatabaseName MyDatabase -DatabaseServer MyDatabaseServer
Objects must be exported as .TXT files. You cannot build an extension based on a .FOB file.
If you use a source control system, you may want to pull the base .TXT files from there.
If you will be adding multilanguage translations for captions or constants, you must first export all of the text strings to file using How to: Add Translated Strings By Importing and Exporting Multilanguage Files.
Create functionality in the development environment.
Use the development environment as usual to create new objects or modify ones to the extent your license allows you. Keep in mind the following rules:
DO NOT make C/AL code modifications.
DO use subscribing to events to execute code.
DO NOT change restricted page and table properties.
In order to get an easy upgrade experience for your extensions, you cannot modify code the way you do in the traditional customization process. Instead, you extend Dynamics NAV functionality by subscribing to programming events that are raised either explicitly in code, or implicitly by the platform. For more information, see Events in Microsoft Dynamics NAV.
Do not add inline comments to your code. Such comments are helpful as internal documentation, but they will cause the extension to fail when you build the extension package.
Write extension upgrade code for new or modified tables in a codeunit. For more information, see How to: Write Extension Upgrade Code.
If you want your extension to support the multilanguage functionality, add CaptionML captions using the development environment or to a copy of the language export file using the directions for translating multilanguage files in How to: Add Translated Strings By Importing and Exporting Multilanguage Files.
Test your application with the extension added.
Export your changed and added application objects to .TXT files.
Export all objects that you added or modified to .TXT files. Use the same export cmdlet from step 1 or manually export within the development environment. They must also be exported as .TXT files and should be placed in a separate directory so that the packaging process can be pointed at them.
Export-NAVApplicationObject -Path MODIFIED -DatabaseName MyDatabase -DatabaseServer MyDatabaseServer
Export the codeunit that contains the upgrade code to a .TXT file. This file must be placed in the folder for delta files that you create in the next step.
Create DELTA files using the Microsoft Dynamics NAV Development Shell cmdlets.
Extension packages are based on application object deltas. Again, you use the application merge utilities in the Microsoft Dynamics NAV Development Shell to distil the changes in the form of application object differences that are stored in DELTA files. Creating an extension uses many of the same concepts and tools as you know from application object deltas. You use the
Compare-NAVApplicationObjectcmdlet to create these delta files.
Compare-NAVApplicationObject -OriginalPath ORIGINAL -ModifiedPath MODIFIED -DeltaPath DELTA
Your delta files must be one-to-one with the objects you have added or modified. You cannot include a single merged delta file. If you output your export file as a single file use the
Split-NAVAppplicationObjectFilecmdlet to create the individual files.
If you will be adding Multilanguage translations for captions or constants, use the
Compare-NAVAppApplicationObjectLanguagecmdlet to calculate the delta between the original version and modified version of the language text files. Include the resulting delta language text file in the sourcepath when building the extension package.
Compare-NAVAppApplicationObjectLanguage -OriginalPath MLORIGINAL -ModifiedPath MLMODIFIED -DeltaPath MLDELTA
Build the extension package.
For more information, see How to: Create an Extension Package.
Debugging your extension is no different than debugging any other customization that you do. But if you have to debug your way through a deployed extension, then you must set your breakpoint and debug from within the runtime environment for the tenant.
Adding Data to your Extension
An extension can include starting or default data that is loaded when the extension is installed. The data to load can only be for a new table that is not company-specific and is added as part of the extension.
As part of developing your extension, you create a new table that will contain this data, add the data, extract the data, and then build the extension package.
To load starting data in a new table
Create a new table for your extension that is not a company-specific table.
This is the table that you want to load the starting data into during the installation.
Populate the table with the starting data that you want loaded when the Extension is installed.
Add a call to the
NAVAPP.LOADPACKAGEDATA(TableNo)system function in the
OnNAVAppUpgradePerDatabasecodeunit for the table.
PROCEDURE OnNavAppUpgradePerDatabase@1(); BEGIN NAVAPP.LOADPACKAGEDATA(50004); END;
Export the table data to file. Use the
Export-NAVAppTableDatacmdlet to export the data from the table to file. When exporting you will provide the path to a folder where you want the .navxdata file created. A data file in the format of TAB <TABLEID>.navxdata will be created, such as TAB10000.navxdata.
Export-NAVAppTableData -ServerInstance DynamicsNAVServer -Path ‘C:\NAVAppTableData’ -TableId 10000
Copy the exported table data file into a source folder for packaging, such as a folder with the name TableData next to the DELTA folder.
Create your extension package, including the folder containing the exported table data file as a source path.
Publish and install the extension.
In certain situations, you may need to load starting data for your extension to existing tables or to company-specific tables. In that case, you can add a new table that serves as a staging table in your extension, and then using a page or codeunit to retrieve the table data from the staging table and load it into the target table.
To use a staging table to load data into an existing table
Create a new table for your extension that is not a company-specific table.
This is the staging table that you want to load the data into during the installation.
Populate the table with the data that you will want to load in the target tables, and then follow steps 3-5 in the previous procedure.
Add a new codeunit that will retrieve the data from the staging table and load it in the company table.
Create a new codeunit.
Add a new function to the codeunit that subscribes to the
Set the Event property to Subscriber.
Set the EventPublisherObject property to Codeunit ApplicationManagement.
Set the EventFunction property to the
When you get asked if you want to overwrite the edited function's signature, choose Yes to continue.
Add your code to copy the data from the staging table to the company table to the new event subscriber function. The code should check if the data has already been copied and if it hasn’t then copy the data.
If the existing table is not a company-specific table, then create a page where the user can select to load the data instead.
Extending Other Extensions
You can extend the functionality that another extension has made available. When you do that, you create a dependency between the original extension and the one extending it. This dependency must be verified and compiled when the new extension is published.
You must have the source code for the extension that you want to extend available in the development environment to use as the base of your app. The steps for creating a dependent app, or, in other words, extending another extension, are outlined below.
If you do not identify a dependency when you build your extension package, publishing your extension results in errors that are caused by base objects missing, and the publish operation will fail.
To create a dependent extension
Import and compile the source code for the extension that you want to extend.
Use the Export-NAVApplicationObjectLanguage cmdlet to establish the new base for your app deltas.
Extend the functionality with your modifications and additions using the development environment.
Use the Export-NAVApplicationObjectLanguage and the Compare-NAVApplicationObject cmdlets to export and create the deltas for your app. Since you are comparing against a base that has the functionality that you are extending, you should only see deltas for your changes.
Create the package for your extension using the
New-NAVAppPackagecmdlets making sure to use the –Dependencies parameter on the
New-NAVAppManifestto identify the NAV extensions that you dependent on.