Study guide
2.3: Multi-Root Workspaces & Project Dependencies
Microsoft Dynamics 365 Business Central Developer MB-820
Track your progress as you read
Finished sections get a check mark.
1 Chapter 1: Business Central Architecture & Platform Foundation
1.1 Business Central Architecture & Extensions Model 1.2 Customization Lifecycle: Cloud (SaaS) vs. On-Premises 1.3 Base Application, System Application & AppSource
2 Chapter 2: Development Environment & Configuration
2.1: Development Environment Setup: VS Code, AL: Go! Projects & Sandboxes 2.2: AL Configuration Files: app.json & launch.json Parameters 2.3: Multi-Root Workspaces & Project Dependencies
3 Chapter 3: Extension Lifecycle: Debugging, Deployment, Multilanguage & Maintenance
3.1 Debugging & Snapshot Debugging in Visual Studio Code 3.2 Extension Deployment & Schema Synchronization Modes 3.3 Multilanguage Development with XLIFF & Translation Files 3.4 Extension Maintenance, Deprecation & Breaking Changes
4 Chapter 4: Tables, Table Extensions & Data Modeling
4.1: Building Tables, Fields, Keys & Data Types 4.2: Table Extensions & Table Modifications 4.3: FlowFields, FlowFilters & Table Relations 4.4: Enums, Enum Extensions & Extensible Types
5 Chapter 5: Pages, Page Extensions & Role Centers
5.1: Page Types, Anatomy & Control Structure 5.2: Building Card, List & Document Pages 5.3: Page Extensions & Page Customizations 5.4: Role Centers, Headlines & Cue Data Modeling
6 Chapter 6: Reports & Document Generation
6.1 Report Architecture, DataItems & Dataset Design 6.2 Report Layouts: RDLC, Word, Excel & Multilanguage 6.3 Document Reports & Request Page Programming 6.4 Processing-Only Reports & Report Substitutions
7 Chapter 7: XMLports & Data Exchange
7.1 XMLport Architecture, Formats & Properties 7.2 XMLport Node Hierarchy, Triggers & Stream Manipulation
8 Chapter 8: Codeunits, Events, Triggers & Interfaces
8.1 Codeunit Types, Execution & SingleInstance Codeunits 8.2 Events, Publishers, Subscribers & Event Isolation 8.3 Interfaces, Polymorphism & Dynamic Codeunit Invocation 8.4 Installation & Upgrade Codeunits, Data Transfer & Archive
9 Chapter 9: Entitlements, Permissions & Queries
9.1 Permission Sets & Permission Set Extensions 9.2 Inherent Permissions, Inherent Entitlements & Security Scoping 9.3 Query Objects: Joins, Aggregation & Query as Report Data Source
10 Chapter 10: UI Customization, User Assistance & Onboarding
10.1 Profile Objects & Custom Page Views in AL 10.2 User Assistance: ToolTips, Teaching Tips & In-App Tours 10.3 Assisted Setup, Guided Experience & Onboarding Checklists
11 Chapter 11: Business Central Design Patterns & Data Process Model
11.1 Functional Table Types: Master Data, Supplemental & Setup Patterns 11.2 Document Standards: Header, Line, History & Journal Architectures 11.3 Data Process Model & Posting Routine Architecture
12 Chapter 12: AL Language Fundamentals, Data Types & Variables
12.1 AL Syntax, Variable Scope, Primitive & Complex Data Types 12.2 Expressions, Control Flow Statements & Built-in Functions 12.3 Access Modifiers (Public, Internal, Local) & Code Scoping
13 Chapter 13: Data Manipulation, Streams & Error Handling
13.1 Record Operations: Get, FindSet, ModifyAll & Filter Functions 13.2 Streams, File Management & TempBlob 13.3 Error Handling: ErrorInfo, TryFunctions & Collectible Errors
14 Chapter 14: Testing, Test Toolkit & Automation
14.1 Testing Architecture & the Test Toolkit 14.2 Authoring Test Codeunits & UI Handler Functions
15 Chapter 15: Telemetry, Performance Optimization & Analyzers
15.1 Telemetry Configuration & Azure Application Insights 15.2 Custom Telemetry Signals with Session.LogMessage & KQL 15.3 Performance Profiler, SetLoadFields & Query Optimization 15.4 AL Analyzers: CodeCop, AppSourceCop, UICop & PTECop
16 Chapter 16: REST Web Services & JSON in AL
16.1 HttpClient, HttpRequestMessage & REST API Consumption 16.2 JSON Processing: JsonObject, JsonArray, JsonValue & JsonToken
17 Chapter 17: API Pages, OData, Read Scale-Out & OAuth
17.1 API Pages (PageType=API), OData Web Services & REST Endpoints 17.2 Bound and Unbound OData Actions with [ServiceEnabled] 17.3 Read Scale-Out Architecture & DataAccessIntent Configuration 17.4 Microsoft Entra ID App Registrations & OAuth 2.0 Integration
2.3: Multi-Root Workspaces & Project Dependencies
Key Takeaways Explain This Topic AI
Visual Studio Code multi-root workspaces (.code-workspace) allow developers to manage, edit, and compile multiple interdependent AL extension projects within a single unified IDE window.
The AL Language extension resolves symbols across open workspace folders directly in memory before querying the .alpackages folder, providing real-time cross-project IntelliSense without manual symbol downloads.
Extension dependencies are declared in app.json using id, name, publisher, and version, establishing a minimum version constraint (>= declared version) and determining build order.
Circular dependencies between AL extensions are strictly prohibited and fail the build; they must be resolved by refactoring shared models and interfaces into a lower-tier Core extension.
Workspace-level settings such as al.packageCachePath centralize symbol storage to a single shared directory, eliminating redundant multi-gigabyte symbol downloads across projects.
Last updated: August 2026
2.3: Multi-Root Workspaces & Project Dependencies
Enterprise Business Central solutions rarely consist of a single monolithic extension. Instead, professional development architectures partition complex business domains into modular, layered applications—such as core frameworks, domain-specific modules, country localizations, and integration connectors. The MB-820 exam tests your mastery of Visual Studio Code multi-root workspaces , project dependency resolution, circular reference elimination, and symbol cache optimization across multi-app architectures.
1. Multi-Root Workspace Architecture ( .code-workspace )
A Visual Studio Code multi-root workspace enables developers to open and work on multiple distinct AL extension project folders simultaneously within a single IDE window. Each folder maintains its own independent app.json , launch.json , and source code tree, while sharing unified workspace settings. {
- "folders": [
- {
- "name": "01 - Contoso Core Library",
- "path": "./ContosoCore"
- },
- {
- "name": "02 - Contoso Logistics Engine",
- "path": "./ContosoLogistics"
- },
- {
- "name": "03 - Contoso Shipping Connector",
- "path": "./ContosoShipping"
- }
- ],
- "settings": {
- "al.packageCachePath": "./.shared-packages",
- "al.enableCodeActions": true,
- "al.incrementalBuild": true,
- "al.codeAnalyzers": [
- "${CodeCop}",
- "${AppSourceCop}"
- ],
- "al.ruleSetPath": "./ruleset.json"
- }
- }
- In-Memory Abstract Syntax Tree (AST) Symbol Resolution
The primary benefit of multi-root workspaces is real-time in-memory symbol resolution :
In a single-project setup, whenever an upstream dependency is modified, developers must recompile the upstream project ( Ctrl+Shift+B ), copy its generated .app package into the dependent project's .alpackages folder, and reload the window.
In a multi-root workspace , the AL Language extension inspects all open workspace folders. When Project B depends on Project A, the language server constructs an in-memory Abstract Syntax Tree (AST) of Project A directly from its raw source code.
Instant Cross-Project IntelliSense : If a developer adds a new public procedure or table field in ContosoCore , that procedure or field is immediately visible in ContosoLogistics and ContosoShipping via IntelliSense without compiling, packaging, or downloading symbols .
2. Project Dependencies & Dependency Graphs
Upstream dependencies are formally declared within the dependencies array of the downstream project's app.json : {
- "id": "3d4e5f6a-7b8c-9d0e-1f2a-3b4c5d6e7f8a",
- "name": "Contoso Logistics Engine",
- "publisher": "Contoso",
- "version": "2.0.0.0",
- "dependencies": [
- {
- "id": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
- "name": "Contoso Core Library",
- "publisher": "Contoso",
- "version": "1.5.0.0"
- }
- ]
- }
- Key Dependency Rules for the MB-820 Exam
Exact Identification : A dependency entry requires four exact attributes: id (GUID), name , publisher , and version . The id is the primary matching key.
Minimum Version Semantics : The version specified in the dependency declaration represents the minimum compatible version . The target runtime environment must have a version installed that is greater than or equal to ( >= ) the declared version (e.g., 1.5.0.0 or higher).
Directed Acyclic Graph (DAG) Compilation Order : The AL compiler builds a dependency graph across all workspace folders. Compilation occurs strictly from the bottom up:
Level 0: Foundation / Core libraries (no dependencies).
Level 1: Domain modules (depend on Level 0).
Level 2: Composite integrations / UI customizations (depend on Level 1 and Level 0).
Breaking Changes Propagation : If a developer modifies a public method signature (e.g., adding a mandatory parameter) or removes a table field in a Level 0 project, all downstream projects will immediately display compiler errors in the Problems pane until updated.
3. Circular Dependencies & Decoupling Strategies
A circular dependency occurs when Extension A depends on Extension B, while Extension B simultaneously depends on Extension A (either directly or transitively through an intermediary Extension C). FATAL ARCHITECTURAL DEFECT (Circular Dependency):
- +-----------------------+ +-----------------------+
- | Extension A | -----------> | Extension B |
- | (Contoso Logistics) | <----------- | (Contoso Billing) |
- +-----------------------+ +-----------------------+
REFACTORED CLEAN ARCHITECTURE (Common Kernel / Interface Pattern):
- +-----------------------+ +-----------------------+
- | Extension A | | Extension B |
- | (Contoso Logistics) | | (Contoso Billing) |
- +-----------------------+ +-----------------------+
- \ /
- \ /
- v v
- +------------------------------+
- | Extension C |
- | (Contoso Core Interfaces) |
- | - Shared Tables & Enums |
- | - Business Event Publishers |
- +------------------------------+
- Circular Dependency Detection
The AL compiler strictly forbids circular references. If a circular loop exists in the dependency graph, symbol resolution fails and the compiler reports that a circular dependency was detected between the listed extensions.
Architectural Remediation Patterns
When two modules require mutual interaction, developers must decouple them using one of two proven design patterns:
Shared Kernel / Common Core Pattern :
Extract the shared tables, enums, interfaces, and integration event publishers into a third foundational extension (e.g., Contoso Core Interfaces ).
Configure both Extension A and Extension B to depend downward on the Core extension.
Event-Driven Decoupling (Publish/Subscribe) :
Instead of Extension A directly invoking a codeunit in Extension B, Extension A declares and raises an Integration Event Publisher .
Extension B subscribes to Extension A's event using [EventSubscriber] .
Extension A remains completely unaware of Extension B, eliminating the dependency from A to B.
Interface Polymorphism :
Declare an AL interface in the Core extension.
Implement the interface within concrete codeunits in Extension A and Extension B.
Use extensible enums to dynamically instantiate the desired implementation at runtime without direct project coupling.
4. Centralized Package Cache Optimization ( al.packageCachePath )
In enterprise multi-app workspaces containing multiple projects, each project by default maintains its own local .alpackages folder. Downloading identical multi-gigabyte symbol files ( Microsoft_Base Application.app , Microsoft_System.app ) for 5 to 10 distinct folders wastes gigabytes of disk space and saturates network bandwidth. {
- "settings": {
- "al.packageCachePath": "c:/AL/SharedSymbols"
- }
- }
Benefits of Centralized Package Caching:
Single Download : When AL: Download Symbols is executed in any project, symbols are downloaded to the centralized folder and immediately shared across all workspace projects.
Disk Footprint Reduction : Reduces workspace disk consumption from ~15 GB down to ~3 GB.
Fast CI/CD Builds : Build scripts can pre-populate the shared symbol directory once prior to executing parallel project builds.
Unified Cache Invalidation : Executing AL: Clear Object Cache flushes the single shared cache, preventing subtle version drift between projects.