TL;DR
Two languages, two extension models and two separate Microsoft Marketplace offer types. Finance & Operations bans overlayering outright and Business Central is additive by construction — but X++ commits you to Chain of Command and its rules about the next keyword, while AL commits you to the object model and the .app package. What travels between them is the engine, not the binary.
AL or X++ — what building on each ERP actually commits you to
Not to a syntax. To an extension model, a packaging format and a Microsoft Marketplace offer type — and all three differ between the two ERPs under the Dynamics 365 umbrella. Business Central is built in AL and ships a .app package. Finance & Operations is built in X++, and its only sanctioned customization framework is extensions.
The choice most teams think they are making is "which language do we hire for". The choice they are actually making is how much of their code Microsoft may move underneath them, and what happens on the update when it does.
What each language actually is — Microsoft's definitions, and what each ships as
- **What the language is** — Business Central — AL:
[GA]The language of the Business Central extension model. "Extensions are a programming model where you define functionality as an addition to existing objects." · Finance & Operations — X++:[GA]"X++ is an object-oriented, application-aware, and data-aware programming language used in enterprise resource planning (ERP) programming and in database applications." - **What it compiles to** — Business Central — AL: Objects "stored as code, known as AL code", saved in files with the
.alfile extension · Finance & Operations — X++: "X++ source code compiles to Microsoft .NET CIL (Common Intermediate Language)." - **Ships as** — Business Central — AL: "Compile extensions as
.apppackage files." · Finance & Operations — X++: Models and packages, deployed as a deployable package - **Marketplace offer type — Business Central — AL: Dynamics 365 Business Central · Finance & Operations — X++: Dynamics 365 Operations Apps**
Sources for the quoted cells: the AL Developing extensions in AL page and the X++ language reference.
One detail for the build-pipeline conversation. On X++: "If any method in a model element (for example, a class, form, or query) fails to compile, the whole compilation fails."
Only one of the two ERPs bans changing the vendor's code, and it says so in one sentence
Finance & Operations states its position without qualification on the Extensibility home page:
"The move to the cloud, together with more agile servicing and frequent updates, requires a less
intrusive customization model, so that updates are less likely to affect custom solutions. This new
model is called extensibility and it replaces customization through overlayering."
"Extensibility is the only customization framework in Finance, Supply Chain, and Commerce.
Overlayering isn't supported."
Business Central arrives at the same place by construction rather than by prohibition: the model is additive from the start. "The extension model is object-based; you create new objects, and extend existing objects depending on what you want your extension to do."
The reason both landed here is the same, and Microsoft names it: "Intrusive customizations are the major obstacle to keeping continuous upgrade costs close to zero" (Intrusive customizations). That page also puts the burden where it lands: "Ultimately, the developer is responsible for avoiding intrusive customizations."
Its principles read as a design contract: "Don't change a method signature." "Don't overlayer. Overlayering replaces the default implementation and prevents multiple solutions from changing the same element."
X++ commits you to Chain of Command, and Chain of Command has rules
Extending an existing F&O method means wrapping it, and the wrapper is governed by the next keyword (Class extension - Method wrapping and Chain of Command):
"In this example, the wrapper around doSomething and the required use of the next keyword
create a Chain of Command (CoC) for the method. CoC is a design pattern where a request is handled by
a series of receivers."
Chain of Command is [GA], available from Platform update 9 onward.
The wrapper is declared with the [ExtensionOf(classStr(...))] attribute on a final class, and it "must have the same signature as the base method". Then the constraints, which are what you are really committing to:
- **You must always call `next` — "Wrapper methods in an extension class must always call next, so that the next method in the chain and, finally, the original implementation are always called." One exception: "The compiler doesn't enforce calls to next for methods with the attribute, Replaceable**."
- **`next` cannot be conditional — "You can't call next conditionally inside an if statement." Nor in "while, do-while, or for** loop statements", nor after a
return, nor inside a logical expression - **Ordering is not yours to choose — "The system randomly runs one of these methods… When the call to the next doSomething** method occurs, the system randomly picks another method in the CoC."
- **Some methods are closed — "If you explicitly mark a method as [Hookable(false)]**, you can't wrap the method in an extension class." Methods marked
finalneed[Wrappable(true)]to be wrappable at all - **Constructors are out** — "You can't extend constructors."
- **The base package may need rebuilding** — To wrap a method in a base package such as Application Suite, "you must recompile that base package on Platform update 9 or later"
Read the ordering row twice. If two ISV (independent software vendor) solutions wrap the same method, neither controls which runs first, and Microsoft's guidance for that world is behavioural rather than technical — the Intrusive customizations page asks you to "Recognize that you are not the only consumer of an extension point."
Microsoft's hedges on the tooling are worth reproducing rather than smoothing. On form-nested concepts — data sources, data fields, controls — "Currently, the X++ editor in Microsoft Visual Studio doesn't support discovery of methods that you can wrap", so signatures come from the documentation. And, on a real gap: "Currently, if a developer uses Chain of Command on purely X++ methods on types inside forms, the code compiles, but the extension methods aren't invoked at runtime. This capability is planned for a future update." [PLAN]
Code that compiles and silently does nothing at runtime is a budgetable risk. It belongs in the estimate.
AL commits you to the object model, the package and one documented gap
Business Central's commitments are lighter and more concrete. Everything is an object — "Table objects define the table schema that holds data", "Codeunits contain code for logical calculations and for the application behavior" — and you extend them through table extension and page extension objects.
The Extensibility overview lists what an AL developer can extend: "tables, enumerations, application areas, pages, reports, code flows, and the security model", where extending code flows means subscribing to events published by base app codeunits.
Three commitments to budget for:
- **Packaging** — "Compile extensions as
.apppackage files… A.apppackage contains the various artifacts that deliver the new functionality" plus "a manifest that specifies the name, publisher, version, and other attributes of the extension." - **A hard naming limit** — "Extension objects can have a name with a maximum length of 30 characters."
- **API objects are closed** — "Extending API pages and queries isn't currently possible in Business Central."
That third one matters to anyone planning an integration: Business Central's Dataverse virtual tables are built on API Pages (see reading and writing Dynamics data). You can consume those APIs freely; you cannot extend the API object itself. A design needing a field on an existing API page is a design change — better found now than in build week.
Before submission, "you can enable the AppSourceCop code analyzer" to validate against Marketplace requirements.
One AppSource listing or two? What we checked, and what it says
Nothing in the Business Central or Finance & Operations developer documentation we opened answers it, which is why it is so often left open. The answer lives in the Partner Center documentation set — a different product's docs entirely.
Plan Dynamics 365 offers for Microsoft Marketplace introduces its listing-options table with the phrase "the three Dynamics 365 offer types" and names them: Dynamics 365 Operations Apps, Dynamics 365 apps on Dataverse and Power Apps, and Dynamics 365 Business Central.
The type is chosen when the offer is created. Both setup pages give the same instruction with a different menu item — "select + New offer > Dynamics 365 Business Central" on one, "select + New offer > Dynamics 365 Operations Apps" on the other. Each type has its own setup, properties and listing pages.
The sharpest available test is the Operations Apps Applicable products list, which Microsoft enumerates in full: "Commerce, Finance, Human Resources, Project Operations, and/or Supply Chain Management". Business Central is not among them.
What we checked, stated precisely. We opened the Partner Center planning page, both offer-setup pages and the Operations Apps properties page. On those pages the two are distinct types selected at creation, with distinct package concepts — a Business Central offer selects a Package type of "Add-on" or "Connect" app, which the Operations Apps offer has no equivalent of. What we did not find is any statement addressing whether a single offer may span both. The documented shape is two offer types and a per-offer choice; we are not asserting a Microsoft prohibition, because we did not read one.
Either way the vendor's plan is the same: two listings, two submissions, two certification passes.
Where we would draw the line
We would not write the optimization itself in either language. X++ and AL are where you integrate, validate and present. A data-science engine belongs on Azure, versioned and deployed on its own cadence — not inside a package that recompiles when Application Suite does.
We would not build anything that depends on Chain of Command ordering. Microsoft says the system picks randomly among wrappers. A design that needs to run before another ISV will fail in an environment you cannot reproduce.
And we would not treat "we know AL" as "we can ship on Finance & Operations". The languages are the smallest difference between them. The extension models, the packaging and the marketplace paths are the real work, and each is duplicated rather than shared.
What to ask this week
- For every extension in your estate, record its language and its package. Any code predating the extension-only model on Finance & Operations is a migration item.
- Ask each ISV in your account whether their solution wraps methods another ISV also wraps. The honest answer is "we don't control the order" — reward it.
- On Business Central, check whether any planned integration needs a field on an existing API page. Microsoft states that is not currently possible; find out before build week.
- Ask any vendor claiming to support both ERPs which offer type each product is listed under. There is a different offer type for each ERP, and the answer tells you whether they have shipped both.
About Cognilium Cognilium builds AI optimization apps for Microsoft Dynamics 365 — companion apps that optimize the pricing, inventory, warehouse and planning decisions your ERP manages but can't optimize. Dynamics is your system of record. Cognilium is your system of intelligence. https://cognilium.ai · https://www.linkedin.com/company/37180269/
Sizing a build on one or both of these ERPs? Book a fifteen-minute call and we will walk the extension model and the packaging path with you live — no deck. https://cognilium.ai
Sources
- Developing extensions in AL
- Extensibility overview (Business Central)
- X++ language reference
- Extensibility home page (Finance & Operations)
- Class extension - Method wrapping and Chain of Command
- Intrusive customizations
- Plan Dynamics 365 offers (Marketplace)
- Business Central offer setup
- Operations Apps offer setup
- Operations Apps offer properties
Sources
- learn.microsoft.com — devenv dev overview
- learn.microsoft.com — devenv extensibility overview
- learn.microsoft.com — xpp language reference
- learn.microsoft.com — extensibility home page
- learn.microsoft.com — method wrapping coc
- learn.microsoft.com — intrusive customizations
- learn.microsoft.com — marketplace dynamics 365
- learn.microsoft.com — dynamics 365 business central offer setup
- learn.microsoft.com — dynamics 365 operations offer setup
- learn.microsoft.com — dynamics 365 operations properties
- learn.microsoft.com — devenv publish code customization
Share this article
Muhammad Mudassir
Founder & CEO, Cognilium AI
Muhammad Mudassir
Founder & CEO, Cognilium AI
Mudassir Marwat's argument is that ERP systems record decisions they never optimise.
