Files

158 lines
9.6 KiB
Markdown
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- Common/DTS.Common/Classes/Groups/ChannelSettings/ChannelSettingRecord.cs
- Common/DTS.Common/Classes/Groups/ChannelSettings/GroupChannelSettingRecord.cs
- Common/DTS.Common/Classes/Groups/ChannelSettings/ChannelSettingBase.cs
generated_at: "2026-04-16T03:18:55.361650+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "48681046c7a61e91"
---
# ChannelSettingRecord, GroupChannelSettingRecord, and ChannelSettingBase Documentation
## 1. Purpose
This module defines core data structures for representing channel configuration settings within the DTS system. It provides three interrelated classes: `ChannelSettingRecord` (a lightweight record of a *type* of channel setting, including its ID, name, and default value), `GroupChannelSettingRecord` (a *specific instance* of a setting applied to a particular channel), and `ChannelSettingBase` (a richer, type-aware implementation of `IChannelSetting` that supports parsing and type conversion of setting values). Together, they enable storage, retrieval, and manipulation of channel-specific configuration parameters across different channel types (analog, digital, squib, UART, CAN, etc.), forming the data layer for channel configuration management.
## 2. Public Interface
### `ChannelSettingRecord`
- **`ChannelSettingRecord()`**
Default constructor; initializes an empty record.
- **`ChannelSettingRecord(IDataReader reader)`**
Populates the record from an `IDataReader` by reading columns `"Id"`, `"SettingName"`, and `"DefaultValue"` using `Utility.GetInt` and `Utility.GetString`.
- **`int Id { get; set; }`**
Unique identifier for this setting *type* (e.g., `"Range"` or `"SquibCurrent"`).
- **`string SettingName { get; set; }`**
Human-readable name of the setting (e.g., `"Range"`).
- **`string DefaultValue { get; set; }`**
Default value string for this setting type (e.g., `"10"` for a range setting).
> *Note:* Inherits from `Common.Base.BasePropertyChanged`, implying `INotifyPropertyChanged` support for UI binding.
---
### `GroupChannelSettingRecord`
- **`GroupChannelSettingRecord()`**
Default constructor; initializes an empty record.
- **`GroupChannelSettingRecord(IDataReader reader, int storedProcedureVersionUsed)`**
Populates the record from an `IDataReader`. If `storedProcedureVersionUsed >= Constants.BULK_GROUPCHANNELSETTINGS_GET_DB_VERSION`, it reads `"ChannelId"` using `Utility.GetLong`; otherwise, `ChannelId` is left uninitialized (default `0`). Always reads `"SettingId"` (`Utility.GetInt`) and `"SettingValue"` (`Utility.GetString`).
- **`GroupChannelSettingRecord(long channelId, int settingId, string settingValue)`**
Constructor for direct initialization with explicit values.
- **`long ChannelId { get; set; }`**
Identifier of the channel to which this setting instance applies.
- **`int SettingId { get; set; }`**
Identifier of the setting *type* (corresponds to `ChannelSettingRecord.Id`).
- **`string SettingValue { get; set; }`**
Actual value string assigned to this setting for the channel.
> *Note:* Inherits from `BasePropertyChanged`, implying `INotifyPropertyChanged` support.
---
### `ChannelSettingBase`
- **`ChannelSettingBase(int settingType, string name, string defaultValue)`**
Constructor initializing `SettingTypeId`, `SettingName`, and `DefaultValue`. `Value` is initialized to `null`.
- **`ChannelSettingBase(IChannelSetting setting)`**
Copy constructor; initializes all properties from another `IChannelSetting` instance.
- **`IChannelSetting Clone()`**
Returns a new `ChannelSettingBase` instance with all properties copied from the current instance.
- **`long ChannelId { get; set; }`**
Channel identifier associated with this setting instance.
- **`int SettingTypeId { get; protected set; }`**
Type ID of the setting (e.g., used to group settings by channel type).
- **`string SettingName { get; protected set; }`**
Name of the setting (e.g., `"Range"`, `"SquibCurrent"`).
- **`string DefaultValue { get; protected set; }`**
Default value string for this setting type.
- **`string Value { get; set; }`**
Current value string for this setting instance.
- **`double DoubleValue { get; set; }`**
Parses `Value` as a `double` (using `InvariantCulture`); if parsing fails, returns `DoubleDefaultValue`. Setting updates `Value`.
- **`double DoubleDefaultValue { get; }`**
Parses `DefaultValue` as a `double` (using `InvariantCulture`).
- **`int IntValue { get; set; }`**
Parses `Value` as an `int`; if parsing fails, returns `IntDefaultValue`. Setting updates `Value`.
- **`int IntDefaultValue { get; }`**
Parses `DefaultValue` as an `int`.
- **`bool BoolValue { get; set; }`**
Parses `Value` as a `bool`; if parsing fails, returns `BoolDefaultValue`. Setting updates `Value`.
- **`bool BoolDefaultValue { get; }`**
Parses `DefaultValue` as a `bool`. If parsing fails and `DefaultValue` is null/empty, returns `false`; otherwise, returns `!DefaultValue.Equals(0)` (note: this is a string comparison, not numeric).
> *Note:* Implements `IChannelSetting`. Constants defined as `public const string` for known setting names (see *Gotchas* for caveats).
---
## 3. Invariants
- **`ChannelSettingRecord`**
- `Id`, `SettingName`, and `DefaultValue` are populated from database columns and must be non-null (except `DefaultValue`, which may be empty or null per `Utility.GetString` behavior).
- `Id` is expected to be unique per setting type.
- **`GroupChannelSettingRecord`**
- `SettingId` must correspond to a valid `ChannelSettingRecord.Id` (enforced externally, not by this class).
- `ChannelId` may be uninitialized (`0`) if constructed via `IDataReader` constructor with `storedProcedureVersionUsed < Constants.BULK_GROUPCHANNELSETTINGS_GET_DB_VERSION`.
- `SettingValue` may be null or empty.
- **`ChannelSettingBase`**
- `SettingName` and `DefaultValue` are set only via constructor and remain immutable after construction (due to `protected set`).
- `Value` is mutable and may be null/empty.
- `DoubleValue`, `IntValue`, and `BoolValue` fall back to their respective `*DefaultValue` properties if `Value` is unparsable.
- `BoolDefaultValue` has non-intuitive behavior: if `DefaultValue` cannot be parsed as `bool`, and is non-empty, it returns `!DefaultValue.Equals("0")` (string comparison), *not* numeric evaluation.
---
## 4. Dependencies
### Dependencies *of* this module:
- **`DTS.Common.Interface.Channels`**
Defines interfaces `IChannelSettingRecord`, `IGroupChannelSettingRecord`, and `IChannelSetting` (consumed by these classes).
- **`DTS.Common.Base`**
Provides `BasePropertyChanged` (base class for `ChannelSettingRecord` and `GroupChannelSettingRecord`).
- **`System.Data`**
Used for `IDataReader` in constructors.
- **`DTS.Common` (internal)**
- `Utility` class (for `GetInt`, `GetString`, `GetLong`).
- `Constants` (for `BULK_GROUPCHANNELSETTINGS_GET_DB_VERSION`).
### Dependencies *on* this module:
- Likely consumed by:
- Data access layers (to populate records from `IDataReader`).
- Channel configuration services (to manage per-channel settings).
- UI layers (via `INotifyPropertyChanged` support).
---
## 5. Gotchas
- **`BoolDefaultValue` logic is error-prone**:
If `DefaultValue` is `"1"` or `"true"`, `bool.TryParse` succeeds. But if `DefaultValue` is `"0"`, `bool.TryParse` fails (since `"0"` is not a valid `bool` string), and `BoolDefaultValue` returns `!DefaultValue.Equals("0")``false`. This is inconsistent with typical `bool` parsing and may cause misinterpretation of `"0"` as `false` only when `bool.TryParse` fails. Prefer explicit `"true"`/`"false"` defaults.
- **`ChannelSettingBase` constants are *not* exhaustive**:
The `public const string` fields list known setting names (e.g., `"Range"`, `"SquibCurrent"`), but are not validated against actual usage. New settings may be added without updating these constants, leading to string literals scattered elsewhere in the codebase.
- **`GroupChannelSettingRecord` constructor behavior depends on `storedProcedureVersionUsed`**:
If `storedProcedureVersionUsed < Constants.BULK_GROUPCHANNELSETTINGS_GET_DB_VERSION`, `ChannelId` is *not* read from the `IDataReader`, leaving it at `0`. This introduces version-dependent data loading logic that may cause silent bugs if versioning is mismanaged.
- **`ChannelSettingBase` does not enforce `Value` format**:
While `DoubleValue`, `IntValue`, and `BoolValue` provide type-safe access, `Value` itself is a raw `string`. No validation ensures `Value` matches the expected format for `SettingName`.
- **`Clone()` returns `IChannelSetting`, not `ChannelSettingBase`**:
The copy constructor is `private`, and `Clone()` returns the interface type, limiting extensibility or deep-copy behavior in subclasses.
- **No null-safety for `DefaultValue` in numeric/bool conversions**:
`DoubleDefaultValue`, `IntDefaultValue`, and `BoolDefaultValue` call `double.Parse`, `int.Parse`, or `bool.TryParse` on `DefaultValue` without null checks. If `DefaultValue` is `null`, this will throw `ArgumentNullException` or `FormatException`.
- **`SettingName` is `protected set`**:
Cannot be modified after construction, but `ChannelSettingBase` is not sealed—subclasses could theoretically override behavior, though no subclasses are visible in the provided source.
- **`ChannelSettingRecord` and `GroupChannelSettingRecord` share naming but serve distinct roles**:
`ChannelSettingRecord` defines a *type* of setting (e.g., `"Range"`), while `GroupChannelSettingRecord` defines an *instance* (e.g., channel 123s `"Range"` = `"10"`). Confusing these roles is a common source of bugs.
None identified beyond the above.