GenMate.DataModels 41.0.0

dotnet add package GenMate.DataModels --version 41.0.0
                    
NuGet\Install-Package GenMate.DataModels -Version 41.0.0
                    
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="GenMate.DataModels" Version="41.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="GenMate.DataModels" Version="41.0.0" />
                    
Directory.Packages.props
<PackageReference Include="GenMate.DataModels" />
                    
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 GenMate.DataModels --version 41.0.0
                    
#r "nuget: GenMate.DataModels, 41.0.0"
                    
#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 GenMate.DataModels@41.0.0
                    
#: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=GenMate.DataModels&version=41.0.0
                    
Install as a Cake Addin
#tool nuget:?package=GenMate.DataModels&version=41.0.0
                    
Install as a Cake Tool

POCO Data Models for the GenMate platform.

Reading a property tree — read this before parsing PropertiesJson

MaterialModel.PropertiesJson and its siblings hold a property tree: a JSON object whose keys are property keys (PropertyTypeKeys). A selector's value is a selector node, whose keys are that selector's option names, each addressing that option's property tree.

A PortGroupModel.PropertiesJson, say:

{
  "alarm_current": 0.5,
  "converter_supply_voltage": {
    "$inherit": "circuit_root",
    "25V": { "converter_supply_voltage_value": 25 },
    "70V": { "converter_supply_voltage_value": 70 }
  }
}

An enum property (PropertyDataType.Enum) is not a selector node: its value is a plain string, one of the property type's Options, and it opens no property tree. A port type's "circuit_address_type": "Sensor" is one. It is never asked of the drafter.

A selector node therefore carries metadata alongside its options, sharing one namespace. Keys beginning with $ (PropertyTreeKeys.ReservedPrefix) are metadata and are never options.

The rule

A selector node's options are exactly its non-reserved members. Enumerate them with PropertyTreeKeys.SelectorOptions, never by iterating the node directly.

foreach (var option in PropertyTreeKeys.SelectorOptions(node.EnumerateObject(), p => p.Name))
{
    // option.Name is an option; option.Value is that option's property tree
}

SelectorOptions is generic over the member type, so it works with whatever JSON parser a consumer already uses — this package deliberately ships no parser of its own, keeping its netstandard2.0 target dependency-free.

Iterating a node directly is a real, observed bug and not a hypothetical one: it takes $inherit for an option, renders it as an empty bogus choice, and writes it back as one, corrupting the authored tree on the next save. Any metadata added to this namespace later breaks such a loop the same way — and leaves a SelectorOptions loop working.

Markers defined today

Key Value Meaning
$inherit a scope name, today only circuit_root (PropertyInheritanceScopes) The selector is answered from the scope the vertex sits on, not from a per-vertex selection, and is never prompted for.

$inherit is authored per authoring object — the material or port group whose property tree it is — not per property key: the device that declares the answer authors the same selector without the marker and is prompted for it as usual, while the devices downstream of it carry the marker and inherit. The same key is therefore inherited on one device and prompted on another, which is why this cannot be a flag on the property definition. It also has to be able to mark a nested selector — converter_supply_voltage authored inside a speaker_wattage branch — which a sibling key at the property level could not address.

An option can never collide with a marker: options are declared only by PropertyTypeDefinition, whose constructor and init accessor reject any option in the reserved namespace. Unrecognised markers should be skipped, not treated as options — which is what SelectorOptions does.

These key strings persist into authored catalogues and customer drawings. Like the enum names in this package, treat them as append-only: add markers, never rename or repurpose one.

Rendering a delete-impact count — read this before displaying a DeleteImpactGroup

DeleteImpactResponse answers "what will deleting this break?" as counts, one DeleteImpactGroup per relationship. Every group ships both label forms, labelPlural and labelSingular:

{
  "referenceType": "port-type",
  "labelPlural": "Port types allowing it",
  "labelSingular": "Port type allowing it",
  "effect": 0,
  "customManagedDistinctionApplies": true,
  "count": 1,
  "countCustom": 1,
  "countManaged": 0
}

There is deliberately no field called label. An asymmetric pair invites a caller to reach for the general-sounding one and render "1 port types allowing it" — the exact bug this shape exists to prevent.

The rule

Pick labelSingular when the count is exactly 1 and labelPlural otherwise, then render it verbatim. Never derive either form from the other.

A count of 0 takes labelPlural, as English does — "0 materials", not "0 material".

Deriving is not merely discouraged, it does not work. Several of these labels are phrases rather than bare nouns, so singularising the last word gives the wrong answer:

Plural Singular Why stripping an s fails
Port types allowing it Port type allowing it The last word has no trailing s; the head noun is in the middle.
Materials using those port types Material using that port type The head noun and the determiner both have to change, in two different places.
Assemblies Assembly Irregular — so are Companies/Company.

This is a real, observed bug and not a hypothetical one: a client that shipped last-word singularisation rendered "1 managed port types allowing it" and "1 custom materials using those port type".

The labels are prose the API authors, so the API owes both forms in full — including the irregulars and the determiners. A client's only job is to choose between them by the count.

customManagedDistinctionApplies is a fixed property of referenceType, not a reading of the numbers: it says whether "custom" and "managed" mean anything for that kind of record at all, so the wording cannot flicker as the data changes. See the XML docs on DeleteImpactGroup for the per-property detail.

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 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 is compatible.  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
41.0.0 0 10/4/2026
40.1.0 59 10/3/2026
40.0.0 61 9/29/2026
39.1.0 45 9/28/2026
39.0.0 68 9/28/2026
38.0.0 73 9/28/2026
37.1.0 73 9/28/2026
37.0.0 79 9/28/2026
36.0.0 96 9/27/2026
35.1.0 88 9/25/2026
35.0.0 90 9/23/2026
34.1.0 302 9/21/2026
34.0.0 86 9/21/2026
33.1.0 433 9/14/2026
33.0.0 125 9/13/2026
32.1.0 164 9/9/2026
32.0.0 152 9/8/2026
31.0.0 94 9/7/2026
30.0.0 160 9/5/2026
29.0.0 169 9/1/2026
Loading failed