This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

View File

@@ -0,0 +1,154 @@
---
source_files:
- Common/DTS.Common.Serialization/TestSetup/Graph/Graph.cs
- Common/DTS.Common.Serialization/TestSetup/Graph/Channel.cs
generated_at: "2026-04-16T03:41:07.285794+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "54ff68752851044a"
---
# Graph
## Documentation: `DTS.Serialization.Graph` and `DTS.Serialization.Graph.Channel`
---
### 1. **Purpose**
This module defines core serialization-friendly data structures (`Graph` and `Channel`) used to represent test setup configurations in the DTS (Dynamic Test System) framework. The `Graph` class encapsulates a test configuration as a named, versioned container of one or more `Channel` instances, each representing a logical test channel tied to either a live `Test.Module.Channel` object or a placeholder for deserialization scenarios. These classes are designed for XML serialization (evidenced by use of `XmlIgnoreAttribute`) and serve as a lightweight, serializable abstraction layer over the richer, runtime `Test.Module` domain model—enabling persistence, transmission, or reconstruction of test setups without coupling to the full test execution engine.
---
### 2. **Public Interface**
#### `DTS.Serialization.TestSetup.Graph`
- **`Graph()`**
Default constructor. Initializes `_Version.Value` to `"1.0.0.0"`, sets `_Name.Value` to `null`, and assigns a new `Guid` to `Identifier`.
- **`void UnSet()`**
No-op method (empty implementation). Purpose unclear from source.
- **`List<Channel> Channels { get; set; }`**
Gets or sets the list of channels in this graph. Initialized to an empty list by default.
- **`string Name { get; set; }`**
Gets or sets the graphs logical name. Defaults to `""`.
- **`string HardwareChannelName { get; set; }`**
Gets or sets a hardware-specific channel name (e.g., physical port label). Defaults to `""`.
- **`string DisplayName { get; }`**
Computed property: concatenates `Name` and `HardwareChannelName` with an underscore (`Name + "_" + HardwareChannelName`). May yield `"_"` if both are empty.
- **`string Version { get; set; }`**
Gets or sets the graph version string. *Note:* Constructor sets `_Version.Value = "1.0.0.0"`, but the backing field `_Version` is initialized with `""` as default—this is overwritten in the constructor.
- **`override string ToString()`**
Returns `Name`.
- **`bool IsSingleChannelGraph { get; }`**
Returns `true` if `Channels` is non-null and contains exactly one element.
- **`Channel FirstChannel { get; }`**
Returns the first element in `Channels`. **Unsafe**: throws `IndexOutOfRangeException` if `Channels` is null or empty.
- **`Test.Module.Channel FirstTestChannel { get; }`**
Returns `FirstChannel.TestChannel`. **Unsafe**: throws `IndexOutOfRangeException` if `Channels` is null/empty, or `NullReferenceException` if `FirstChannel.TestChannel` is null.
- **`Guid Identifier { get; private set; }`**
Unique identifier for the graph instance. Set only in constructor via `Guid.NewGuid()`.
#### `DTS.Serialization.TestSetup.Graph.Channel`
- **`Channel()`** *(private)*
Internal constructor. Sets `ChannelId = "Not Set"`. Not used externally.
- **`Channel(Test.Module.Channel channel)`**
Constructor for wrapping an existing runtime `Test.Module.Channel`. Populates:
- `ParentTestModule` = `channel.ParentModule`
- `TestChannel` = `channel`
- `ChannelId` = `channel.ChannelId`
- `ChannelGroupName` = `channel.ChannelGroupName`
*Note:* A `TODO` comment indicates intent to use a unique key (e.g., `Identifier`) instead of `HardwareChannelName`—but this is not implemented.
- **`Channel(string channelId)`**
Constructor for placeholder channel (e.g., deserialization). Sets `ParentTestModule = null`, `TestChannel = null`, and `ChannelId = channelId`.
- **`Channel(long groupChannelId)`**
Constructor for placeholder channel from numeric ID. Sets `ParentTestModule = null`, `TestChannel = null`, and `ChannelId = groupChannelId.ToString()`.
- **`override string ToString()`**
Returns `TestChannel.ToString()` if `TestChannel` is non-null; otherwise `"Not Set"`.
- **`string ChannelId { get; set; }`**
Logical channel identifier (e.g., `"TestObjectSerial_ChannelType_ChannelId"`). Used as a unique key *in practice*, though not enforced.
- **`string ChannelGroupName { get; set; }`**
Group name for the channel (e.g., `"Axial"`, `"Radial"`).
- **`string Name { get; }`**
Returns `TestChannel.ChannelDescriptionString` if `TestChannel` is non-null; otherwise `"Not Set"`.
- **`string SensorName { get; }`**
Returns `TestChannel.ChannelDescriptionString.ToString()` if `TestChannel` is non-null; otherwise `"Not Set"`.
*Note:* Redundant with `Name`; likely legacy or for XML serialization compatibility.
- **`string AxisUnit { get; }`**
Returns engineering units (`AnalogInputChannel.EngineeringUnits`) if `TestChannel` is an `AnalogInputChannel`; otherwise `"EU"`.
- **`string SerialNumber { get; }`**
Returns `ParentTestModule.SerialNumber` if `ParentTestModule` is non-null; otherwise `"Not Set"`.
- **`Test.Module ParentTestModule;`**
Public field referencing the parent test module (e.g., sensor or DAQ device). May be `null` for placeholder channels.
- **`Test.Module.Channel TestChannel;`**
Public field referencing the underlying runtime channel object. May be `null` for placeholder channels.
---
### 3. **Invariants**
- **`Graph.Identifier`** is assigned exactly once during construction and never modified afterward.
- **`Graph.Channels`** is never `null` after construction (initialized to `new List<Channel>()` in `_Channels`).
- **`Graph.Version`** is initialized to `"1.0.0.0"` in the constructor, overriding the default `""` in `_Version`.
- **`Channel.ChannelId`** is always set (non-null) and used as a logical identifier, though uniqueness is not enforced by the class.
- **`Graph.DisplayName`** may be malformed (e.g., `"_"`, `"_" + HardwareChannelName`) if `Name` is empty or whitespace.
- **`Graph.FirstChannel`** and **`Graph.FirstTestChannel`** assume `Channels.Count >= 1`; no bounds checking is performed.
---
### 4. **Dependencies**
- **Internal Dependencies**:
- `DTS.Common.Utilities` (namespace)
- `DTS.Common.Utilities.DotNetProgrammingConstructs` (for `Property<T>` wrapper)
- `System`, `System.Collections.Generic`, `System.Xml.Serialization`
- **External Dependencies**:
- `Test.Module` (namespace): referenced via `Test.Module.Channel`, `Test.Module.ParentTestModule`, `Test.Module.AnalogInputChannel`, and `Test.Module.Channel.ChannelDescriptionString`.
*This implies a hard dependency on the `Test.Module` assembly (likely `DTS.TestModule.dll` or similar).*
- `Exceptional`: Base class for both `Graph` and `Channel` (inherited from `TestSetup.Exceptional`).
- **Depended Upon By**:
- Serialization infrastructure (e.g., XML serializers, given `[XmlIgnore]` usage).
- Test setup persistence layers (e.g., saving/loading `.xml` test configurations).
- UI or tooling that consumes serialized test setups.
---
### 5. **Gotchas**
- **`Graph.FirstChannel` and `Graph.FirstTestChannel` are unsafe**: No null/empty checks—accessing them on an empty `Channels` list will throw `IndexOutOfRangeException`.
- **`DisplayName` may produce misleading output**: Concatenation of `Name` and `HardwareChannelName` without trimming or validation can yield `"_"` or `"Name_"`.
- **`Channel` constructors are inconsistent in initialization**:
- `Channel(Test.Module.Channel)` populates `ParentTestModule` and `TestChannel`.
- `Channel(string)` and `Channel(long)` leave them `null`.
Code must check for null `TestChannel`/`ParentTestModule` before accessing derived properties (`Name`, `SerialNumber`, etc.).
- **`SensorName` duplicates `Name` logic**: Both use `TestChannel.ChannelDescriptionString`, but `SensorName` calls `.ToString()` explicitly—likely redundant or legacy.
- **`HardwareChannelName` is unused in `Channel` constructor**: The `TODO` comment suggests `Identifier` should be set from `HardwareChannelName`, but this is not implemented. `Identifier` remains `Guid.NewGuid()` (graph-level), while `Channel` has no `Identifier` field.
- **`Channel` has no `Identifier` field**: Unlike `Graph`, `Channel` lacks a unique ID—relying on `ChannelId` (a string) as a de facto key, but this is not enforced or validated.
- **`UnSet()` is a no-op**: Its purpose is unclear; may be a placeholder for future cleanup or legacy pattern.
- **`Property<T>` behavior**: The `Property<T>` wrapper (from `DotNetProgrammingConstructs`) likely handles change notifications or serialization metadata, but its exact semantics (e.g., null handling, validation) are not visible here. Default values (`""`, `new List<Channel>()`) are set in field initializers, but constructor overrides (e.g., `Version = "1.0.0.0"`) may conflict with expectations.