3.1 Visual Studio Extension Models & Packages
Key Takeaways
- A Package is the physical deployment and compilation unit that produces a single .NET assembly DLL, whereas a Model is a design-time logical container of metadata and source code.
- Under PackagesLocalDirectory, metadata adheres strictly to the directory structure <Package>\<Model>\Ax<ElementType>\<ElementName>.xml, governed by descriptor files in <Package>\Descriptor\<Model>.xml.
- Overlayering is permanently sealed; all customization must occur through the extension model to ensure non-destructive application updates and support One Version continuous servicing.
- A Visual Studio project is bound to exactly one Model, and models declare explicit, non-circular dependencies via their Model Descriptor XML.
- The standard Microsoft model hierarchy flows unidirectionally from ApplicationPlatform through ApplicationFoundation, Directory, SourceDocumentation, and ApplicationSuite, with custom models referencing these standard layers.
Visual Studio Extension Models & Packages
Quick Answer: In Dynamics 365 Finance and Operations, a Package is the physical deployment and compilation unit that compiles into a single .NET assembly (
.dll), while a Model is a design-time metadata container representing a logical feature set. Development occurs inside Visual Studio Projects, each bound to exactly one model. All metadata resides on disk underPackagesLocalDirectory\<Package>\<Model>\Ax<ElementType>\*.xml, defined by a model descriptor inPackagesLocalDirectory\<Package>\Descriptor\<Model>.xml. Overlayering is permanently sealed; customizations must use extensions (additive metadata and Chain of Command) so that Microsoft can continuously service base packages without breaking customizations.
1. Core Architectural Concepts: Packages, Models, and Projects
Understanding the precise separation of responsibilities between Packages, Models, and Visual Studio Projects is critical for both real-world solution architecture and the MB-500 exam.
+-------------------------------------------------------------------------+
| PACKAGE (Deployment & Compilation Boundary) |
| Compiles into: <PackageName>.dll + .netmodule files |
| |
| +--------------------------+ +---------------------------------+ |
| | MODEL A (Design-time) | | MODEL B (Design-time) | |
| | Metadata & X++ Code | | Metadata & X++ Code | |
| | Descriptor: ModelA.xml | | Descriptor: ModelB.xml | |
| +--------------------------+ +---------------------------------+ |
+-------------------------------------------------------------------------+
^ ^
| (Bound to Model A) | (Bound to Model B)
+-----------------------+ +-----------------------+
| VS Project 1 (.rnrproj)| | VS Project 2 (.rnrproj)|
+-----------------------+ +-----------------------+
The Package
- Compilation Boundary: A package is the unit of compilation. When built, all models residing inside a package are compiled together into a single .NET assembly (
<PackageName>.dll) stored in the package'sbindirectory, along with symbol files (.pdb) and netmodules. - Deployment Boundary: Software Deployable Packages (SCDPs) deployed via Lifecycle Services (LCS) or Power Platform Admin Center (PPAC) contain compiled packages. You deploy binaries at the package level, never individual models or individual elements.
- Isolation: A package can reference other packages, but circular dependencies between packages are strictly prohibited by the build system.
The Model
- Design-Time Metadata Container: A model is a logical grouping of elements (tables, forms, classes, EDTs, enums, extensions) and source files. It is purely a design-time construct.
- Multiplicity: A single package can contain multiple models. Historically, Microsoft shipped packages containing multiple models (for example, the
ApplicationSuitepackage originally contained bothApplicationSuiteandApplicationSuiteElectronicReportingmodels). However, current development best practices dictate creating one model per package for custom solutions to simplify deployment and versioning. - Descriptor File: Every model possesses an identity file called a Model Descriptor (
<ModelName>.xml) located in<PackagesLocalDirectory>\<PackageName>\Descriptor\.
The Visual Studio Project
- Developer Work Unit: Projects in Visual Studio (using the Finance and Operations project system,
.rnrproj) organize elements during development. - Strict 1:1 Binding to Model: A project can belong to exactly one model. You specify this model during project creation (or in the project properties). You cannot place elements belonging to Model A and Model B inside the same Visual Studio project.
- No Runtime Existence: A project does not exist at runtime or deployment. It is purely a developer-facing filter and compilation trigger.
Comparison: Package vs. Model vs. Project
| Architectural Attribute | Package | Model | Project |
|---|---|---|---|
| Primary Role | Compilation and deployment boundary | Design-time metadata and source container | Developer IDE workspace and build organizer |
| Physical Output | <Package>.dll, .pdb, .netmodule | No distinct binary; merged into package DLL | .rnrproj file; no deployment artifact |
| File System Location | PackagesLocalDirectory\<Package> | PackagesLocalDirectory\<Package>\<Model> | Developer source folder / solution directory |
| Dependency Specification | Declared indirectly via model references | Declared explicitly in <Model>.xml descriptor | References determined by the parent model |
| Multiplicity | Contains 1 or more models | Belongs to exactly 1 package | Bound to exactly 1 model |
| Version Control Scope | Entire folder or model folder committed | Granular XML files committed | Project file committed to track active items |
2. File System Architecture Under PackagesLocalDirectory
Finance and Operations uses a metadata-driven architecture where every AOT element is stored as an individual, human-readable UTF-8 XML file on disk. This replaced the legacy monolithic database store (the AX 2012 ModelStore).
Physical Location
On developer virtual machines (Cloud-Hosted Environments or local VHDs), metadata is hosted under the AOS service directory:
- Standard path:
K:\AosService\PackagesLocalDirectoryorC:\AOSService\PackagesLocalDirectory.
Hierarchy Anatomy
The directory structure follows a strict naming convention:
<PackagesLocalDirectory>\
<PackageName>\
bin\ --> Compiled binaries (.dll, .pdb)
Descriptor\ --> Model descriptor metadata
<ModelName>.xml --> Declares dependencies & identity
<ModelName>\
AxClass\ --> X++ classes (.xml)
AxTable\ --> Tables (.xml)
AxTableExtension\ --> Table extensions (.xml)
AxForm\ --> Forms (.xml)
AxFormExtension\ --> Form extensions (.xml)
AxEdt\ --> Extended Data Types (.xml)
AxEnum\ --> Base Enumerations (.xml)
AxEnumExtension\ --> Enum extensions (.xml)
AxSecurityRole\ --> Security Roles (.xml)
AxLabelFile\ --> Label metadata & text files
Concrete Examples of Disk Paths
- Standard Customer Table:
PackagesLocalDirectory\ApplicationSuite\Foundation\AxTable\CustTable.xml - Custom Table Extension in Model
ContosoCoreinside PackageContosoCore:PackagesLocalDirectory\ContosoCore\ContosoCore\AxTableExtension\CustTable.ContosoCore.xml - Custom Runnable Class (Job) in Model
ContosoCore:PackagesLocalDirectory\ContosoCore\ContosoCore\AxClass\ContosoInvoiceBatchJob.xml - Model Descriptor for
ContosoCore:PackagesLocalDirectory\ContosoCore\Descriptor\ContosoCore.xml
Key Architecture Rule: Because every element is an individual XML file, version control systems (Git or Azure DevOps TFVC) can track granular line-by-line diffs, perform parallel branch merges, and execute pull request code reviews without locking an entire binary database.
3. Model Descriptors & Dependency Architecture
A model cannot access elements, tables, classes, or EDTs defined in another model unless it has declared an explicit dependency on that model's package.
Anatomy of AxModelInfo in the Model Descriptor
The descriptor file located at <Package>\Descriptor\<Model>.xml contains serialized AxModelInfo metadata. Key properties include:
<Name>: The unique internal name of the model.<Publisher>: The organization or ISV authoring the model (e.g.,Contoso Ltd).<VersionMajor>,<VersionMinor>,<VersionBuild>,<VersionRevision>: Semantic version numbers.<Description>: Human-readable summary of the model's functional scope.<ModuleReferences>: The collection of package/model dependencies this model requires to compile.
<?xml version="1.0" encoding="utf-8"?>
<AxModelInfo xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Name>ContosoCustomizations</Name>
<Publisher>Contoso Corporation</Publisher>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<VersionBuild>0</VersionBuild>
<VersionRevision>1</VersionRevision>
<Description>Contoso Enterprise Extensions for Accounts Receivable</Description>
<ModuleReferences>
<string>ApplicationPlatform</string>
<string>ApplicationFoundation</string>
<string>Directory</string>
<string>SourceDocumentation</string>
<string>ApplicationSuite</string>
</ModuleReferences>
</AxModelInfo>
The Standard Microsoft Model Hierarchy
Microsoft organizes the standard application into layered packages and models. Dependencies flow strictly downward:
- ApplicationPlatform: Contains kernel runtime primitives, base system tables (
UserInfo,Batch), foundational system classes, primitive data types, and core security definitions. - ApplicationFoundation: References
ApplicationPlatform. Contains organizational hierarchies, the Global Address Book (GAB) core framework, number sequences, and SysOperation execution infrastructure. - Directory: References
ApplicationFoundation. Houses the party model (DirPartyTable, contact info, address resolution). - SourceDocumentation / SourceDocumentationTypes: References
ApplicationFoundationandDirectory. Implements the underlying accounting framework, monetary distribution rules, and subledger journal entries. - ApplicationSuite: References all lower layers. Houses core ERP business logic: General Ledger, Accounts Receivable (
CustTable), Accounts Payable (VendTable), Inventory Management (InventTable), Sales Orders (SalesTable), and Purchase Orders (PurchTable).
+-------------------------------------------------------------+
| ApplicationSuite |
| (CustTable, VendTable, SalesTable, InventTable, etc.) |
+-------------------------------------------------------------+
| | |
v v |
+------------------------+ +-----------------------+ |
| SourceDocumentation | | Directory | |
+------------------------+ +-----------------------+ |
| | |
+----------------+----------------+ |
v v
+--------------------------------------------------+
| ApplicationFoundation |
+--------------------------------------------------+
|
v
+--------------------------------------------------+
| ApplicationPlatform |
+--------------------------------------------------+
Dependency Rules for Developers
- Compilation Rule: If code in
ContosoModelreferencesCustTable,ContosoModelmust referenceApplicationSuite. If it only referencesGlobalfunctions or system tables, referencingApplicationPlatformsuffices. - Missing Reference Error: If you write
CustTable custTable;in a model that does not referenceApplicationSuite, the compiler produces an error: "The name 'CustTable' does not denote a class, a table, or an extended data type." - Acyclic Rule: Circular references are rejected at compile time (Model A cannot reference Model B if Model B references Model A).
4. The Extension Model vs. Sealed Overlayering
One of the most foundational architectural shifts evaluated on the MB-500 exam is the complete elimination and sealing of overlayering in favor of the extension model.
The Legacy Overlayering Paradigm (Sealed)
In Dynamics AX 2012 and early versions of Dynamics 365, developers used overlayering:
- Custom code was injected directly into standard Microsoft models within higher layers (e.g., VAR, CUS, USR layers).
- A developer could open standard classes like
SalesLineTypeand edit source lines directly inside Microsoft's methods. - The Pain Point: Whenever Microsoft released a Cumulative Update, hotfix, or service pack, existing customizations were overwritten or produced extensive merge conflicts. Upgrades required hundreds of hours of code conflict resolution and regression testing.
- The Sealing: Starting with Platform Update 11 (PU11) and finalized in Dynamics 365 Finance and Operations version 8.0, Microsoft sealed all standard models. Overlayering is impossible; developers cannot edit standard source files or insert custom code directly into Microsoft packages.
The Modern Extension Paradigm
Under the extension model, Microsoft packages are compiled assemblies that developers treat as immutable black boxes:
- Additive Metadata: To add fields, field groups, or indexes to a standard table (e.g.,
CustTable), developers create a Table Extension (CustTable.ContosoExtension) in their own model. The extension file contains only the delta (the new fields or modified properties). The baseCustTable.xmlremains untouched. - Additive Behavior (Chain of Command - CoC): To wrap business logic around standard methods, developers create extension classes decorated with
[ExtensionOf(tableStr(CustTable))]and utilizenextcalls. Custom logic executes before, after, or around base logic without touching Microsoft source files. - Event Handlers & Delegates: Developers subscribe to pre/post data events (
OnInserting,OnValidatedWrite) or application delegates. - Independent Deployment & Zero-Downtime Servicing: Because custom code resides in separate packages, Microsoft can update
ApplicationSuite.dllduring monthly One Version platform updates without touching or recompiling partner assemblies, guaranteeing non-destructive updates.
Comparison: Overlayering vs. Extension Model
| Feature / Dimension | Legacy Overlayering (Sealed) | Modern Extension Model |
|---|---|---|
| Customization Location | Same package/model as base code (higher layer) | Separate model in a separate package |
| Source Modification | Directly edited Microsoft base source code | Microsoft source code is read-only; deltas stored in extension files |
| Compilation Target | Recompiled base package assembly with custom code | Compiles into custom, independent assembly DLL |
| Upgrade Impact | High conflict rate; code merges required per update | Zero source merge conflicts; non-destructive servicing |
| Method Customization | Inline edits within standard method body | Chain of Command (next call) or Event Handlers |
| Table Customization | Direct column additions to base table definition | Table extension (AxTableExtension) containing only delta fields |
| Microsoft One Version Support | Completely incompatible with continuous updates | Architecturally required for continuous monthly updates |
5. Exam Traps & Real-World Pitfalls
- Exam Trap 1: Missing Module Reference Compile Error. A question presents a scenario where a developer creates a new class in a custom model
ContosoTaxand declares a variable of typeSalesTable. The build fails with "The name 'SalesTable' does not denote a class, a table, or an extended data type", despiteSalesTableclearly existing in the AOT. The root cause is that the developer forgot to add a reference toApplicationSuitein theContosoTaxModel Descriptor. - Exam Trap 2: Project Spanning Multiple Models. The exam asks how to configure a single Visual Studio project to hold both a table extension in
ModelAand a form extension inModelB. The correct answer is that this is impossible: a Visual Studio project can belong to only one model. The developer must create two separate projects. - Exam Trap 3: Physical Folder Placement Errors. If an extension element XML is copied manually into
PackagesLocalDirectory\ApplicationSuite\ApplicationSuite\AxTableExtension\, the compiler will reject it or fail to track it becauseApplicationSuiteis sealed. All custom extensions must reside within the custom package directory (e.g.,PackagesLocalDirectory\ContosoPackage\ContosoModel\AxTableExtension\). - Exam Trap 4: Circular Model Dependencies. If
ModelAreferencesModelB, and a developer attempts to add a reference fromModelBtoModelAto access a newly created helper class, Visual Studio will block the operation with a circular dependency violation.
A developer creates a new Visual Studio project bound to a custom model named 'ContosoSalesTax'. In a new class, the developer writes the line 'CustTable custTable;'. During compilation, the build fails with the error: "The name 'CustTable' does not denote a class, a table, or an extended data type." What is the root cause of this build failure and the appropriate resolution?
Which of the following statements accurately characterizes the architectural distinction between a Package and a Model in Dynamics 365 Finance and Operations?
A developer needs to inspect the physical XML file that represents a custom table extension named 'CustTable.ContosoCore' on a development virtual machine. Where is this file located within the file system?
Why did Microsoft permanently eliminate and seal overlayering in favor of the extension model starting with Finance and Operations version 8.0?