mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-10-05 14:46:55 +01:00
Add foundational AL developer knowledge (#195)
Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
38ad6b8810
commit
dd833133e0
23 changed files with 483 additions and 4 deletions
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
bc-version: [all]
|
||||
domain: upgrade
|
||||
keywords: [appversion, dataversion, moduleinfo, install-codeunit, upgrade-codeunit, version-context]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [all]
|
||||
---
|
||||
|
||||
# `ModuleInfo.AppVersion` changes meaning with execution context
|
||||
|
||||
## Description
|
||||
|
||||
`ModuleInfo.AppVersion()` is the installed version during normal operation, the version being installed inside install code, and the target version inside upgrade code. It is therefore not the source data version during an upgrade. In upgrade code, `DataVersion()` describes the version of the existing data, whether from the currently installed app or the version most recently uninstalled.
|
||||
|
||||
## Best Practice
|
||||
|
||||
Interpret `AppVersion()` as the code package entering the context and `DataVersion()` as the existing data state. Prefer upgrade tags for controlling individual migration steps; when version information is needed for diagnostics or preconditions, name variables so target app version and source data version cannot be confused.
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Reading `AppVersion()` from an upgrade codeunit and treating it as the version being upgraded from. The comparison actually observes the target package and can skip or misroute migration logic.
|
||||
|
||||
## Reference
|
||||
|
||||
[Create proper installation and upgrade codeunits](https://learn.microsoft.com/en-us/training/modules/easy-application-upgrade/3-installation-upgrade-codeunits)
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
codeunit 50641 "Sample Upgrade Part One"
|
||||
{
|
||||
Subtype = Upgrade;
|
||||
|
||||
trigger OnUpgradePerCompany()
|
||||
begin
|
||||
CreateUpgradeState();
|
||||
end;
|
||||
|
||||
local procedure CreateUpgradeState()
|
||||
begin
|
||||
end;
|
||||
}
|
||||
|
||||
codeunit 50642 "Sample Upgrade Part Two"
|
||||
{
|
||||
Subtype = Upgrade;
|
||||
|
||||
trigger OnUpgradePerCompany()
|
||||
begin
|
||||
// This can run before Part One; object IDs do not sequence upgrade codeunits.
|
||||
MigrateDataThatRequiresUpgradeState();
|
||||
end;
|
||||
|
||||
local procedure MigrateDataThatRequiresUpgradeState()
|
||||
begin
|
||||
end;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
codeunit 50640 "Sample Upgrade Good"
|
||||
{
|
||||
Subtype = Upgrade;
|
||||
|
||||
trigger OnUpgradePerCompany()
|
||||
begin
|
||||
CreateUpgradeState();
|
||||
MigrateDependentData();
|
||||
end;
|
||||
|
||||
local procedure CreateUpgradeState()
|
||||
begin
|
||||
end;
|
||||
|
||||
local procedure MigrateDependentData()
|
||||
begin
|
||||
end;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
bc-version: [all]
|
||||
domain: upgrade
|
||||
keywords: [install-codeunit, upgrade-codeunit, execution-order, subtype-install, subtype-upgrade, sequencing]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [all]
|
||||
---
|
||||
|
||||
# Separate install or upgrade codeunits have no execution order
|
||||
|
||||
## Description
|
||||
|
||||
An extension can contain multiple `Install` or `Upgrade` codeunits, but Business Central does not guarantee the order in which codeunits of the same subtype execute. Upgrade trigger phases are ordered globally, yet one codeunit's `OnUpgradePerCompany` must not assume another codeunit's same-phase trigger already ran. Object ID and source-file order do not provide sequencing.
|
||||
|
||||
## Best Practice
|
||||
|
||||
Keep separate install or upgrade codeunits independent. When two steps have a real dependency, coordinate them from one owning trigger in the required order; use upgrade tags to make each completed step idempotent.
|
||||
|
||||
See sample: [`install-and-upgrade-codeunits-have-no-order.good.al`](install-and-upgrade-codeunits-have-no-order.good.al).
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Splitting dependent steps into separate codeunits and relying on names, object IDs, or declaration order. The dependent codeunit can run first and fail or observe partially migrated data.
|
||||
|
||||
See sample: [`install-and-upgrade-codeunits-have-no-order.bad.al`](install-and-upgrade-codeunits-have-no-order.bad.al).
|
||||
|
||||
## Reference
|
||||
|
||||
[Create proper installation and upgrade codeunits](https://learn.microsoft.com/en-us/training/modules/easy-application-upgrade/3-installation-upgrade-codeunits)
|
||||
Loading…
Add table
Add a link
Reference in a new issue