Files
2026-04-17 14:55:32 -04:00

154 lines
8.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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.