154 lines
8.7 KiB
Markdown
154 lines
8.7 KiB
Markdown
---
|
||
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 graph’s 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. |