TALXIS.Platform.Metadata.Validation
0.5.0
Prefix Reserved
See the version list below for details.
dotnet add package TALXIS.Platform.Metadata.Validation --version 0.5.0
NuGet\Install-Package TALXIS.Platform.Metadata.Validation -Version 0.5.0
<PackageReference Include="TALXIS.Platform.Metadata.Validation" Version="0.5.0" />
<PackageVersion Include="TALXIS.Platform.Metadata.Validation" Version="0.5.0" />
<PackageReference Include="TALXIS.Platform.Metadata.Validation" />
paket add TALXIS.Platform.Metadata.Validation --version 0.5.0
#r "nuget: TALXIS.Platform.Metadata.Validation, 0.5.0"
#:package TALXIS.Platform.Metadata.Validation@0.5.0
#addin nuget:?package=TALXIS.Platform.Metadata.Validation&version=0.5.0
#tool nuget:?package=TALXIS.Platform.Metadata.Validation&version=0.5.0
TALXIS Platform Metadata
Typed metadata model, SolutionPackager XML serialization, and workspace validation for Dataverse and Power Platform solution projects.
This library is the shared metadata kernel used by TALXIS tooling. It models solution components, validates unpacked solution workspaces, preserves source ownership, and calculates Dataverse-style solution layers without depending on the Dataverse SDK.
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 |
Unified workspace validation: XSD validation, JSON validation, duplicate GUID checks, model loading, and load diagnostics with file/line/column locations where available. |
All packages target netstandard2.0.
Install
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.
What it is for
- Build tools that need to inspect or transform unpacked Dataverse solution projects.
- Language servers and editors that need typed model loading plus diagnostics with source locations.
- CLI validation and scaffolding workflows.
- Release pipelines that need deterministic solution metadata checks before packaging/import.
- Future Dataverse/source-control synchronization where one in-memory workspace contains multiple managed and unmanaged solutions.
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 tracks release-critical solution state separately:
Solutions- loaded solution manifests.SolutionComponentMemberships- which solution contains or root-owns a component, mirroring Dataversesolutioncomponentmembership.ComponentSourceSnapshots- source-owned payloads loaded from solution projects for diagnostics and write-back.Layers- Dataverse-style component layer stacks used for effective-state calculation.
Solution layers
The model follows Dataverse ALM terminology:
- Managed solution projects contribute ordered managed layers.
- Unmanaged solution projects contribute source-owned snapshots of the shared
Activelayer. - The Active/unmanaged layer sits above managed layers.
- Most component types use top-wins resolution.
- Model-driven apps, forms, and site maps are mergeable component types in Dataverse; the library also includes a merge strategy for ribbon customization payloads.
Layer membership, source ownership, and effective state are intentionally separate. This is important 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);
}
Validation includes XML schema checks, JSON checks for flow definitions, duplicate GUID detection, typed model loading, and load diagnostics. Consumers should use the returned file path, line, and column to place editor squiggles where the problem was found.
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 preserves unknown XML and original formatting where possible. If a workspace contains multiple solutions, Write(...) 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 unknown XML and source documents 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, and CLI output.
- Explicit export intent - multi-solution workspaces require
WriteSolution(...). - Dependency-light - the core model is pure
netstandard2.0; XML and validation packages 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.
Related projects
| Consumer | Usage |
|---|---|
| TALXIS CLI | Workspace validation, component scaffolding, language server integration. |
| TALXIS Build SDK | Build-time validation, packaging, and version stamping. |
| TALXIS Templates | Safe workspace manipulation from template post-actions. |
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.5.0)
- TALXIS.Platform.Metadata.Serialization.Xml (>= 0.5.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.