AL Extensions: Extending an Extension

Something I’ve been meaning to write about since I started developing extensions is how to extend another extension, or in other words, the process of creating a dependent extension.

For the sake of keeping things straight in this post, I am going to refer to the following 2 extensions:

  1. Parent: the extension that is being depended on.
  2. Child: is dependent on the Parent extension.

So, without further ado, here we go!

First, develop and build the Parent extension. Take note of the following values from the app.json of the Parent extension:

ExtendingExtension1

Now publish the Parent extension to your development system so that we can download the symbols for the Child extension.

Time to move to developing the Child extension, where we need to specify the dependency to the Parent extension. We do that using the following property in the app.json file.

ExtendingExtension2

Using the id, name, publisher, and version values from the Parent extension, we populate the property as follows:

ExtendingExtension3

As soon as you save the app.json file, you will be prompted that symbols are missing. This is because the AL compiler is now looking for the symbols for the dependent extensions.

Click the Download Symbols button in the VS Code notification and download the symbols form the development database where you published the Parent extension.

Take note that the dependencies property accepts an array of values, which means you can specify multiple dependency extensions.

Once the symbol download is complete, you will be able to reference any objects, events, functions, etc. that are available in the Parent extension. You’ll also be able to extend the Parent extension as needed.

Be Aware

  • Make sure that when you publish your extensions, you must do the extension that are depended on first (e.g. Parent). If you try and publish the extension with the dependency first (e.g. Child), it will error stating that references do not exist in the database.
  • When you remove extensions, you must remove the extensions that have the dependencies first (e.g. Child) as you cannot remove an extension that has other extensions depending on it.
  • If you update any of the extensions that are being depended on in your development database, you must also change the corresponding version in the dependencies property of any extension that is dependent on it. Once this is done you will be prompted to download the new symbols file. If you don’t do this you will be developing off of an old version of the symbols ad publishing the extension may fail.

How is this useful?

  • A Dynamics NAV ISV can use this method to create a “library” extension that contains standard functionality that is required to be available across one or more functional extensions.
    • By the way, this scenario is fully supported for any extensions submitted to AppSource. The library extension does not appear in AppSource. When a customer installs the functional extension, the library extension will also get installed.
  • A Dynamics NAV partner could create an extension that contains some common functionality they deliver to all of their customers. They could then create a dependent extension that contains a customized layer on top of the original extension that is unique to each customer.
  • A Dynamics NAV partner needs to extend another partner’s extension.
    • If you are going to do this, you must have access to getting the symbols for the extension you are building on top of. You don’t need the actual .al source files, just the symbols file.
  • A customer who develops their own custom solution can build their own extension and make it dependent on another extension that’s in their system.

Until next time, happy coding!

Advertisements

AL Extensions: Reading JSON info with Powershell

A quick post today on how to read values from a JSON file with PowerShell.

PowerShell contains the commandlet ConvertFrom-Json, which as its name implies, converts a JSON object into a PowerShell object, from which you can then access the values and read them into variables, etc.

Let’s assume we have a file named MyFile.json, which contains the following JSON object:

{
   "id": "123456",
   "name": "MyObjectName"
}

We can convert this into a PowerShell object with the following code:

$JsonObject = Get-Content -Raw -Path .\MyFile.json | ConvertFrom-Json

We can then read the value of  name into a variable like this:

$Name = $JsonObject.Name

SO WHAT?

As the title of this post suggests, we can make use of this handy code with our AL extensions.

In my previous post, I showed you how to create a custom AL extension build task with Visual Studio Code. You can expand on this and launch a PowerShell script to execute the ALC compiler. When you do that, one of the parameters you can supply to the compiler is the output path and resulting app file name. By using the app.json file that is part of every AL extension, you can utilize things such as the extension publisher, name, version, etc. in your compiler process.

You can do something like the following…

$JsonObject = Get-Content -Raw -Path .\app.json | ConvertFrom-Json

$ExtensionName = $JsonObject.Publisher + '_' + $JsonObject.Name + '_' + $JsonObject.Version + '.app'

$CompilerPath = 'C:\Users\<username>\.vscode\extensions\Microsoft.al-0.10.13928\bin'

$ALProjectFolder = 'C:\MyProjectFolder'
$ALPackageCachePath = Join-Path -Path $ALProjectFolder -ChildPath '.alPackages'
$AlPackageOutFilePath = Join-Path -Path 'C:\MyCustomOutputFolder' -ChildPath $ExtensionName

Set-Location -Path $CompilerPath
.\alc.exe /project:$ALProjectFolder /packagecachepath:$ALPackageCachePath /out:$AlPackageOutFilePath

…which would replicate the same file name that the out of box compile process does, but will still allow you to direct the file to be output to a custom path. For example, maybe a shared AL package cache that you use for multiple developers.

Until next time, happy coding!