--- 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 123’s `"Range"` = `"10"`). Confusing these roles is a common source of bugs. None identified beyond the above.