TALXIS.Platform.Metadata.Validation
0.6.0
Prefix Reserved
dotnet add package TALXIS.Platform.Metadata.Validation --version 0.6.0
NuGet\Install-Package TALXIS.Platform.Metadata.Validation -Version 0.6.0
<PackageReference Include="TALXIS.Platform.Metadata.Validation" Version="0.6.0" />
<PackageVersion Include="TALXIS.Platform.Metadata.Validation" Version="0.6.0" />
<PackageReference Include="TALXIS.Platform.Metadata.Validation" />
paket add TALXIS.Platform.Metadata.Validation --version 0.6.0
#r "nuget: TALXIS.Platform.Metadata.Validation, 0.6.0"
#:package TALXIS.Platform.Metadata.Validation@0.6.0
#addin nuget:?package=TALXIS.Platform.Metadata.Validation&version=0.6.0
#tool nuget:?package=TALXIS.Platform.Metadata.Validation&version=0.6.0
TALXIS Platform Metadata
An open-source metadata model for model-driven platforms. It provides typed C# representations of entities, attributes, forms, views, option sets, solutions, and solution layers, with SolutionPackager XML serialization and validation for Dataverse and Power Platform solution projects.
Why this exists
Dataverse solution projects contain the source of truth for platform metadata, but most tools still have to work with raw XML, environment-specific APIs, or ad-hoc scripts. TALXIS Platform Metadata provides a shared kernel that defines what platform components are and how they behave so build tools, CLIs, templates, language servers, and future runtime services can reason about the same model.
It does not store business data, execute plugins, run workflows, or require the Dataverse SDK. It is the type system and workspace model that those higher-level tools can build on.
What this is
- A typed metadata model for source-controlled Dataverse and Power Platform solution projects.
- A roundtrip-safe SolutionPackager XML reader/writer.
- A validation layer for XML schemas, JSON payloads, duplicate GUIDs, and typed model loading.
- A Dataverse-aligned solution model that separates solution membership, source ownership, and effective layer state.
- A foundation for future metadata runtime, import/export, dependency analysis, language server, and live synchronization work.
Who uses it
| Consumer | Usage |
|---|---|
| TALXIS CLI | Workspace validation, component scaffolding, and language server integration. |
| TALXIS Build SDK | Build-time validation, packaging checks, and version stamping. |
| TALXIS Templates | Safe workspace manipulation from template post-actions. |
| Runtime and synchronization services | Future live Dataverse/source-control synchronization and metadata runtime scenarios. |
Use it when you need to inspect, validate, transform, or export unpacked Dataverse solution metadata without taking a dependency on live environment APIs.
Where this is going
The long-term plan is to make this a lightweight, embeddable metadata runtime that can replicate the important parts of the Dataverse solution framework outside Dataverse:
- Load one or more managed and unmanaged solution projects into a single workspace.
- Resolve effective component state from Dataverse-style layer stacks.
- Import and uninstall solutions against an in-memory metadata runtime.
- Build a dependency graph for validation, uninstall safety, and impact analysis.
- Provide type-safe workspace manipulation APIs for CLI and template scenarios.
- Power editor and language-server diagnostics from the same model used by builds.
- Support future live Dataverse/source-control synchronization.
See docs/roadmap.md and docs/runtime-architecture.md for the detailed plan.
Packages
| Package | Purpose |
|---|---|
TALXIS.Platform.Metadata |
Core in-memory metadata model for entities, attributes, relationships, forms, views, apps, roles, workflows, solution manifests, component definitions, and solution layers. |
TALXIS.Platform.Metadata.Serialization.Xml |
Roundtrip-safe reader/writer for unpacked SolutionPackager XML workspaces, including Power Automate flow JSON and generic component passthrough. |
TALXIS.Platform.Metadata.Validation |
Workspace validation: XSD validation, JSON validation, duplicate GUID checks, typed model loading, and load diagnostics with file/line/column locations where available. |
All packages target netstandard2.0.
dotnet add package TALXIS.Platform.Metadata
dotnet add package TALXIS.Platform.Metadata.Serialization.Xml
dotnet add package TALXIS.Platform.Metadata.Validation
Add only the packages you need. The core model package has no Dataverse SDK, HTTP, SQL, or runtime service dependency.
Capabilities
Metadata model
Typed representations of common Dataverse solution metadata:
- Entity - table definitions with ownership, activity type, attributes, relationships, keys, and audit settings.
- Attribute - column definitions with types, constraints, option sets, and localized labels.
- Relationship - one-to-many, many-to-one, and many-to-many metadata with cascade behavior.
- Option set - global and local choices with localized labels.
- Form - form XML metadata and mergeable form structure.
- View - saved query metadata with FetchXML and layout XML.
- Security role - role and privilege metadata.
- Workflow and flow definition - classic workflow metadata and Power Automate flow payloads.
- App, site map, plugin, web resource, and generic components - typed or passthrough metadata for source-controlled solution contents.
Solution model
The model separates concepts that Dataverse treats differently:
- Solutions - loaded solution manifests.
- Solution component memberships - which solution contains or root-owns a component.
- Source snapshots - source-owned payloads loaded from individual solution projects for diagnostics and write-back.
- Layers - Dataverse-style component layer stacks used for effective-state calculation.
- Component definitions - per-type behavior such as identity, merge behavior, overwrite behavior, and dependency metadata.
Serialization
TALXIS.Platform.Metadata.Serialization.Xml reads and writes unpacked SolutionPackager projects. It is designed for source-controlled workspaces where unnecessary diffs are costly:
- Preserves original XML documents and unknown elements where possible.
- Loads single-solution and multi-solution workspaces.
- Tracks source ownership so one solution can be exported from a combined workspace.
- Handles generic components that do not yet have a dedicated typed model.
Validation
TALXIS.Platform.Metadata.Validation validates a workspace as files on disk and as a typed model:
- XML schema validation for embedded SolutionPackager schemas.
- JSON validation for flow definition payloads.
- Duplicate GUID detection.
- Reader/load diagnostics for malformed component files.
- File, line, and column information where available.
Core concepts
Workspace
Workspace is the in-memory representation of one or more unpacked solution projects. It contains typed component collections such as Entities, Forms, Views, Workflows, FlowDefinitions, and GenericComponents.
It also contains solution-layer state needed for ALM scenarios:
SolutionsSolutionComponentMembershipsComponentSourceSnapshotsLayers
Solution layers
The model follows Dataverse ALM terminology:
Active (unmanaged) maker customizations, one shared layer
Managed solution N installed in import order
Managed solution 2
Managed solution 1
System platform baseline
Managed solution projects contribute ordered managed layers. Unmanaged solution projects contribute source-owned snapshots of the shared Active layer. Most component types use top-wins resolution; mergeable component types can combine layer payloads.
Layer membership, source ownership, and effective state are intentionally separate. This matters because multiple unmanaged solutions can contain the same component while Dataverse still exposes a single Active layer.
Validate a workspace
using TALXIS.Platform.Metadata.Validation;
var validator = new WorkspaceValidator();
var report = validator.ValidateDirectory("src/Solutions/Core");
foreach (var result in report.Results)
{
Console.WriteLine($"{result.Severity}: {result.FilePath}({result.Line},{result.Column}) {result.Message}");
}
if (report.LoadedComponents != null)
{
Console.WriteLine(report.LoadedComponents);
}
Consumers should use the returned file path, line, and column to place editor squiggles or produce build diagnostics at the source of the problem.
Load and write one solution project
using TALXIS.Platform.Metadata.Serialization.Xml;
var reader = new XmlWorkspaceReader();
var workspace = reader.Load("src/Solutions/Core");
Console.WriteLine($"Solutions: {workspace.Solutions.Count}");
Console.WriteLine($"Entities: {workspace.Entities.Count}");
var writer = new XmlWorkspaceWriter();
writer.Write(workspace, "artifacts/Core");
XmlWorkspaceWriter.Write(...) preserves unknown XML and original formatting where possible. If a workspace contains multiple solutions, it throws so callers must choose which solution project to export.
Load multiple solutions into one workspace
using TALXIS.Platform.Metadata;
using TALXIS.Platform.Metadata.Serialization.Xml;
var reader = new XmlWorkspaceReader();
var workspace = reader.LoadMany(new[]
{
new SolutionWorkspaceSource("src/Solutions/BaseManaged", importOrder: 0),
new SolutionWorkspaceSource("src/Solutions/AppManaged", importOrder: 10),
new SolutionWorkspaceSource("src/Solutions/UnmanagedCustomizations", importOrder: 100)
});
var accountStack = workspace.Layers.FindStack(ComponentType.Entity, "account");
var effectiveAccount = accountStack == null ? null : workspace.Layers.Resolve(accountStack);
Console.WriteLine($"Loaded solutions: {workspace.Solutions.Count}");
Console.WriteLine($"Component memberships: {workspace.SolutionComponentMemberships.Count}");
Console.WriteLine($"Source snapshots: {workspace.ComponentSourceSnapshots.Count}");
Console.WriteLine($"Layer stacks: {workspace.Layers.Stacks.Count}");
LoadMany(...) requires each SolutionWorkspaceSource to contain exactly one solution manifest. ImportOrder is caller-defined so Package Deployer order, manual import order, or test fixtures can be represented explicitly.
Export one solution from a multi-solution workspace
using TALXIS.Platform.Metadata.Serialization.Xml;
var writer = new XmlWorkspaceWriter();
writer.WriteSolution(workspace, "UnmanagedCustomizations", "artifacts/UnmanagedCustomizations");
WriteSolution(...) exports the selected solution project using source ownership metadata. It does not blindly write the currently effective Active snapshot into every solution.
Work with layers directly
using TALXIS.Platform.Metadata;
using TALXIS.Platform.Metadata.Components;
using TALXIS.Platform.Metadata.Solutions;
var layers = new SolutionLayerManager();
var managed = new Solution { UniqueName = "Base", IsManaged = true };
layers.ImportManagedLayer(
managed,
importOrder: 0,
new[]
{
new LayerComponentDescriptor(
ComponentType.Entity,
"account",
new EntityMetadata { LogicalName = "account" })
});
var active = new Solution { UniqueName = "LocalCustomizations", IsManaged = false };
layers.ImportActiveLayerSnapshot(
active,
importOrder: 100,
new[]
{
new LayerComponentDescriptor(
ComponentType.Entity,
"account",
new EntityMetadata { LogicalName = "account", IsAuditEnabled = true })
});
var stack = layers.FindStack(ComponentType.Entity, "account");
var effective = stack == null ? null : layers.Resolve(stack);
Use ImportManagedLayer(...) for managed solution imports and ImportActiveLayerSnapshot(...) for unmanaged source projects. Avoid treating every unmanaged solution as a separate runtime layer; unmanaged projects share the Dataverse Active layer.
Design principles
- Roundtrip safe - preserve original documents, unknown XML, and source-owned payloads where possible.
- Dataverse-aligned - model solution manifests, memberships, source snapshots, and component layers as distinct concepts.
- Diagnostics-friendly - keep file paths and source locations for validators, language servers, CLI output, and build errors.
- Explicit export intent - multi-solution workspaces require callers to choose the solution they are writing.
- Dependency-light - the core model is pure
netstandard2.0; XML serialization and validation add only the dependencies they need.
Current scope
Implemented:
- Typed metadata model for common Dataverse solution components.
- Solution manifest, publisher, root component, component definition, and layer models.
- Single- and multi-solution workspace loading.
- Source-owned snapshots and solution/component membership tracking.
- Explicit single-solution export from multi-solution workspaces.
- XSD, JSON, duplicate GUID, and model-load validation.
Tracked follow-up work:
- Complete dependency graph and uninstall-safety simulation.
- Package Deployer import-order discovery.
- Patch, holding, and staged upgrade semantics.
- Managed property and publisher customizability enforcement.
- Complete solution component type parity.
- Live Dataverse provider/source-control synchronization.
See docs/ for architecture notes, runtime design, and the roadmap.
Contributing
See CONTRIBUTING.md for development setup and guidelines.
License
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Newtonsoft.Json (>= 13.0.4)
- Newtonsoft.Json.Schema (>= 4.0.1)
- TALXIS.Platform.Metadata (>= 0.6.0)
- TALXIS.Platform.Metadata.Serialization.Xml (>= 0.6.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.