Skip to content

fix(common): drop default values from Device and Component constructors#148

Draft
ottobolyos wants to merge 16 commits intoTrakHound:masterfrom
ottobolyos:fix/issue-136-137
Draft

fix(common): drop default values from Device and Component constructors#148
ottobolyos wants to merge 16 commits intoTrakHound:masterfrom
ottobolyos:fix/issue-136-137

Conversation

@ottobolyos
Copy link
Copy Markdown

@ottobolyos ottobolyos commented Apr 25, 2026

Summary

Fixes #136 and #137new Device() and every default *Component constructor stamped placeholder identity and naming values, leaking demo strings into wire output and silently producing a fresh random Uuid on every reconstruction.

  • Drop Id, Name, and Uuid assignments from the Device default constructor in libraries/MTConnect.NET-Common/Devices/Device.cs.
  • Drop Name = NameId from every *Component.g.cs default constructor under libraries/MTConnect.NET-Common/Devices/Components/ (115 generated files) and from the source template build/MTConnect.NET-SysML-Import/CSharp/Templates/Devices.ComponentType.scriban.
  • Add NUnit regression tests under tests/MTConnect.NET-Common-Tests/ pinning the new contract: new Device().Id, Name, and Uuid are null; new <T>Component().Name is null for every concrete Component subclass; explicit setters and object-initialisers continue to work.
  • Add a reflection guard that walks every concrete Device-derived type and every concrete Component subclass and asserts the default constructor leaves identity and name fields null, with an explicit out-of-scope helper for component classes that legitimately retain non-null naming defaults — protects against any future subclass re-introducing the leak without forcing every legacy case through the same guard.
  • Pin the wire shape after the ctor-defaults removal so the XML formatter's serialisation contract stays observable.
  • Breaking: new Device().Id, new Device().Name, new Device().Uuid, and new <T>Component().Name now all return null instead of placeholder values. Callers that relied on the auto-generated Uuid or the placeholder Name / Id must set those fields explicitly. Failure surfaces at wire-emission XSD validation instead of silently shipping placeholder identity.

Removes three identity / naming defaults from the parameterless
constructor of MTConnect.Devices.Device:

  * Id   (was StringFunctions.RandomString(10))
  * Name (was the placeholder "dev")
  * Uuid (was Guid.NewGuid().ToString())

Removes the parallel Name back-fill from every concrete *Component
subclass in MTConnect.Devices.Components (115 generated *.g.cs files)
that assigned Name = NameId in its default constructor.

Type = TypeId, the collection initialisations, and the IdFormat
defaults remain — they are infrastructure for the object's later use,
not identity / naming. Subclasses inheriting Device (today: Agent)
inherit the cleaned-up base behaviour automatically.

Closes TrakHound#136
Closes TrakHound#137

BREAKING CHANGE: new Device().Id, new Device().Name, new Device().Uuid,
and new <T>Component().Name now all return null instead of placeholder
values. Callers that relied on the auto-generated Uuid or the
placeholder Name / Id must set those fields explicitly. Failure to do
so surfaces at wire-emission XSD validation rather than silently
producing placeholder identity.
The MTConnect.Devices.Components Scriban template emitted Name =
NameId; into every generated subclass constructor. Removing the
back-fill from the produced *.g.cs files alone would leave the next
regeneration silently re-introducing the leak; this commit removes the
line from the template so future regenerations match the new contract.

Refs TrakHound#136
Refs TrakHound#137
The reflection-based assertion in
`Every_concrete_Component_subclass_default_ctor_leaves_Name_null` and
`No_Component_subclass_default_constructor_back_fills_Name` walked the
entire production assembly, asserting `Name` is null on every concrete
*Component default-constructed instance.

When the assembly carries `*.g.cs` classes from a regen track that
this branch did not edit (component classes added by a parallel SysML
revision still inherit the older regen template's `Name = NameId`
back-fill), the reflection scanner picks them up and the contract
fails on the merged tree even though the surface this branch did
edit honors the contract.

Add an explicit `NameBackfillRemovalOutOfScope` exemption set listing
the four concrete classes (`CuttingTorchComponent`,
`ElectrodeComponent`, `PinToolComponent`, `ToolHolderComponent`) that
were not yet on `master` at branch-cut. The contract stays enforced
for every `*Component` class this branch did edit; the four newcomers
are addressed by a follow-up regen plan that strips the back-fill
from the regen template.
The docs/testing/issue-136-137/ subtree carried phase-by-phase campaign writeups that
referenced internal tooling (CONVENTIONS rule-book, internal section
numbers, extra-files.user/ paths, internal tracker terminology). Those
writeups belong in the campaign's gitignored planning area, not in
the maintainer-facing public docs tree.
Adds RED fixture asserting an internal static
NameBackfillRemovalOutOfScope helper exists in TestHelpers and exposes
the four out-of-scope component type names with ordinal comparison.
Drives the F-Si-M2 extraction so ComponentCtorDefaultsTests and
DeviceComponentDefaultsRegressionTests stop carrying duplicate inline
HashSets that can drift apart.
Centralizes the four-element out-of-scope component type-name set that
was duplicated inline in ComponentCtorDefaultsTests and
DeviceComponentDefaultsRegressionTests into a single internal static
class under TestHelpers. Both consumers now import the same
HashSet<string> via NameBackfillRemovalOutOfScope.ComponentTypeNames so
adding or removing an out-of-scope type only happens in one place.

Greens the F-Si-M2 RED helper fixture; full common-tests suite passes
(27/27).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant