TedToolkit.Step21 2026.9.17

dotnet add package TedToolkit.Step21 --version 2026.9.17
                    
NuGet\Install-Package TedToolkit.Step21 -Version 2026.9.17
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TedToolkit.Step21" Version="2026.9.17" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TedToolkit.Step21" Version="2026.9.17" />
                    
Directory.Packages.props
<PackageReference Include="TedToolkit.Step21" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add TedToolkit.Step21 --version 2026.9.17
                    
#r "nuget: TedToolkit.Step21, 2026.9.17"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package TedToolkit.Step21@2026.9.17
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=TedToolkit.Step21&version=2026.9.17
                    
Install as a Cake Addin
#tool nuget:?package=TedToolkit.Step21&version=2026.9.17
                    
Install as a Cake Tool

TedToolkit.Step21 package guide

TedToolkit.Step21 generates strongly typed C# from one or more EXPRESS schemas, then reads, edits, validates, and writes ISO 10303-21 exchange structures through a schema-neutral runtime. Generated entities are mutable classes with reference identity; generated schema descriptors are sealed singleton classes.

Install and generate a schema

dotnet add package TedToolkit.Step21

Add each .exp file to the consumer project as an MSBuild additional file:

<ItemGroup>
  <AdditionalFiles Include="Schemas/catalog.exp" />
</ItemGroup>

The generator consumes all supplied schemas as one closed set. Invalid EXPRESS syntax, binding, unsupported validation-reachable execution, or generated C# name collisions produce source-located build diagnostics and withhold the affected generated schema atomically.

For an EXPRESS schema named catalog, generated types are placed in TedToolkit.Step21.Schemas.Catalog, with its descriptor available as SchemaDescriptor.Instance.

Read, navigate, edit, validate, and write

using TedToolkit.Step21;
using TedToolkit.Step21.Schemas.Catalog;
using CatalogSchemaDescriptor = TedToolkit.Step21.Schemas.Catalog.SchemaDescriptor;

using var input = File.OpenText("catalog.p21");
var structure = ExchangeStructure.Read(
    input,
    [CatalogSchemaDescriptor.Instance]);

foreach (var product in structure.Entities.OfType<Product>())
{
    product.Name = product.Name.Trim();
}

var validation = structure.Validate();
if (!validation.IsValid)
{
    foreach (var failure in validation.Failures)
    {
        Console.Error.WriteLine($"{failure.Code}: {failure.Path}: {failure.Message}");
    }

    return;
}

using var output = File.CreateText("catalog-edited.p21");
structure.Write(output);

ExchangeStructure.Read accepts the complete explicitly supplied descriptor set, performs parse/bind/hydrate/validation atomically, and returns no partial model. structure.Entities is a live read-only population enumeration. Generated entity-valued properties expose the actual generated entity interfaces, including forward, shared, cyclic, aggregate-contained, same-schema, and supported multi-schema references.

Distributed references use the additive overload with ExchangeStructureReadOptions. Supply an absolute base URI and an IPart21ResourceProvider that returns only caller-authorized bytes or in-memory directory entries. The runtime resolves URI/anchor chains, ZIP or directory roots, shared entity identity, and $ outcomes; it never opens a path or network connection implicitly. Part21ResourceLimits bounds the complete per-read graph, and IPart21ResourceConverter is the explicit hook for another source format. Part21ProcessingLimits.Default is a shared finite policy for root input, URI/archive-entry size, CMS work, and atomic output. Use ExchangeStructureReadOptions.WithProcessingLimits(...) or the write-options overload to apply a stricter immutable policy without enabling any additional I/O or trust capability.

SCHEMA_POPULATION resources use the same shared resolver graph and expose transitive population entities through structure.SchemaPopulationEntities. FILE_POPULATION supports all three Annex E determination methods. For cross-schema domain equivalence, use ExchangeStructureReadOptions.WithDomainEquivalenceProvider with a caller-owned provider for the complete relation and physical-parameter projection; the runtime performs target-schema allocation, hydration, identity-alias control, and validation without requiring a Part 22 repository or inferring compatibility by name or shape. Population message digests require a signature, use the first signature section's digest algorithm over the referenced file bytes, and can verify content-only resources without materializing a false exchange model.

Use structure.WriteEntity(writer, entity) when only one registered entity-instance record is required; its overload accepts explicit Part21ProcessingLimits. All write operations validate and size-check the final staged output before producing destination characters.

Construct a structure

Construction uses the same generated types and descriptor; every registration names its destination DataSection explicitly:

var descriptor = CatalogSchemaDescriptor.Instance;
var header = new HeaderSection(
    new FileDescription(["generated"], "3;1"),
    new FileName(
        "catalog.p21",
        "2026-08-22T00:00:00",
        ["author"],
        ["organization"],
        "TedToolkit.Step21",
        "consumer",
        ""),
    new FileSchema([descriptor.Name.Value]));
var structure = new ExchangeStructure(header, [descriptor]);
var section = new DataSection(descriptor.Name);
structure.DataSections.Add(section);

var product = new Product("name");
structure.Add(section, product);
using var output = File.CreateText("catalog-created.p21");
structure.Write(output);

Property, aggregate, registration, and removal edits may temporarily make the graph invalid. Call structure.Validate() for side-effect-free feedback; read/write boundaries enforce validation themselves.

Failure boundaries

Stage Public evidence
Part 21 syntax ExchangeStructureSyntaxException.Diagnostics
Schema/physical binding ExchangeStructureBindingException.Diagnostics
Read-time model validation ExchangeStructureReadValidationException.ValidationResult
Unsupported operation ExchangeStructureCapabilityException.Diagnostics
Write-time validation ExchangeStructureWriteValidationException.ValidationResult; no output is produced
Destination I/O The underlying TextWriter exception propagates unchanged

Diagnostics use stable codes and optional SourceLocation values containing only file path plus 1-based line and column. Duplicate descriptor schema names throw ArgumentException before input is consumed.

Delivered boundary

  • Complete ISO 10303-21:2016 Edition 3 clear-text syntax and ISO 10303-11:2004 Edition 2 EXPRESS syntax.
  • Closed-set schema binding, generated scalar/nominal/SELECT/aggregate/entity types, descriptor-based hydration/projection, and the documented statically generated validation-reachable EXPRESS subset.
  • Simple mappings plus the documented source-bounded complex mapping profile, including nested ONEOF/ANDOR expressions and inherited/redeclared components.
  • Named same-schema and governed multi-schema populations, local cross-section references, deterministic canonical writing, and semantic read-write-read equivalence.
  • A reflection-free, dynamic-code-free package graph verified by a real win-x64 Native AOT consumer publish/run.

Explicit limits

  • Physical anchor items, tags, all four occurrence-name categories, UUID anchor identity, and schema-neutral REFERENCE declarations can be read, edited, validated, canonically written, and reread; see the conformance record.
  • External resource acquisition is opt-in through per-read capabilities; local fragments, external clear text, in-memory directories, ZIP roots/subsidiaries, UUID registry responses, and other-format conversion are supported. The legacy overload keeps unresolved-reference diagnostics, and no overload performs implicit I/O.
  • Signature sections are decoded as detached CMS. Optional per-read verification accepts trust only through explicit time, signer-certificate revocation input, roots, additional or embedded certificates; SignatureReports retains results for every signed resource. Signed writing validates callback output against an independent canonical content snapshot and remains zero-output atomic on failure.
  • The complex mapping profile is bounded to at most eight concrete leaves and 256 candidate combinations per root. Complete evaluated-set validity beyond that profile is not claimed because the supplied ISO 10303-11 files omit Annex B. Domain equivalence is explicit and schema-qualified; ISO 10303-22 repositories and inferred compatibility are outside the package contract.
  • This is not a general EXPRESS interpreter: arbitrary algorithmic RULE/function bodies and cross-schema executable dependencies are outside the delivered subset. The package exposes no public parser context, raw syntax model, reader/writer façade, registry, or resolver.
  • There is no JSON or XML serialization contract, extension hook, attribute model, or dependency.
  • Writing is canonical and semantically equivalent; it is not byte-preserving and does not retain comments or original formatting.

The package ships netstandard2.0 and net8.0 runtime assets. Later .NET consumers select the net8.0 asset. The analyzer is packaged as build-time infrastructure; analyzer implementation libraries do not become consumer runtime assets. Native AOT proof currently executes on win-x64, without implying that this is the only usable runtime identifier.

Product 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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2026.9.17 64 9/17/2026
2026.9.11 82 9/11/2026