--- source_files: - DataPRO/Modules/PreviousDBVersions/Version57/DatabaseExport/Classes/TestMetaData/CustomerDetails.cs - DataPRO/Modules/PreviousDBVersions/Version57/DatabaseExport/Classes/TestMetaData/LabratoryDetails.cs - DataPRO/Modules/PreviousDBVersions/Version57/DatabaseExport/Classes/TestMetaData/TestEngineerDetails.cs generated_at: "2026-04-16T04:59:22.874172+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "283afdf9f6a03436" --- # Documentation: Test Metadata Wrappers (Version 57) ## 1. Purpose This module provides managed wrapper classes for low-level `ISO.*Details` types (`CustomerDetails`, `LabratoryDetails`, `TestEngineerDetails`) used in database export operations for Version 57 of the database schema. Its primary role is to encapsulate and standardize access to these domain entities—offering lazy-loaded, sorted, and deduplicated collections via singleton list managers (`CustomerDetailsList`, `LabratoryDetailsList`, `TestEngineerDetailsList`). It ensures consistent handling of a special "(none)" placeholder entry and provides thread-safe access to metadata used in test reporting and export workflows. ## 2. Public Interface ### `CustomerDetails` - **`CustomerDetails()`** Default constructor. Initializes internal `_customerDetails` with a new `ISO.CustomerDetails`, setting its `Name` to `"(none)"`. - **`CustomerDetails(ISO.CustomerDetails customerDetails)`** Copy constructor. Creates a new `ISO.CustomerDetails` instance from the provided `customerDetails`. - **`string Name { get; set; }`** Gets or sets the `Name` property of the underlying `ISO.CustomerDetails`. - **`ISO.CustomerDetails GetISOCustomer()`** Returns the internal `ISO.CustomerDetails` instance. - **`override string ToString()`** Returns the `Name` property. ### `CustomerDetailsList` - **`static CustomerDetailsList CustomerList { get; }`** Singleton accessor. - **`CustomerDetails[] Customers { get; }`** Returns a sorted (by `Name`, ordinal) array of all `CustomerDetails`, including the "(none)" entry. Thread-safe via `lock` and lazy initialization. - **`CustomerDetails[] GetAllCustomers()`** Returns a fresh array containing a new "(none)" `CustomerDetails` followed by all `CustomerDetails` created from `ISO.CustomerDetails.GetAllCustomerDetails()`. - **`CustomerDetails GetCustomerDetail(string name)`** Returns the first `CustomerDetails` in `Customers` (parallel query) matching `name`, or `null` if none found. --- ### `LabratoryDetails` - **`LabratoryDetails()`** Default constructor. Initializes `_lab` with a new `ISO.LabratoryDetails`, setting `Name` to `"(none)"`. - **`LabratoryDetails(ISO.LabratoryDetails lab)`** Copy constructor. Creates a new `ISO.LabratoryDetails` instance from `lab`. - **`string Name { get; set; }`** Gets or sets the `Name` property of `_lab`. - **`ISO.LabratoryDetails GetIsoLab()`** Returns the internal `_lab` instance. - **`override string ToString()`** Returns the `Name` property. ### `LabratoryDetailsList` - **`protected LabratoryDetailsList()`** Protected constructor (enforces singleton via private instantiation). - **`static LabratoryDetailsList LabratoryList { get; }`** Singleton accessor. - **`LabratoryDetails[] Labs { get; }`** Returns a sorted (by `Name`, ordinal) array of all `LabratoryDetails`, including "(none)". Thread-safe via `lock` and lazy initialization. - **`LabratoryDetails GetLab(string name)`** Returns the `LabratoryDetails` for `name` from the internal `_labs` dictionary (if populated), or `null`. Includes exception handling (logs via `APILogger` on failure). - **`private LabratoryDetails[] GetAllLabs()`** Returns a fresh array containing a new "(none)" `LabratoryDetails` followed by all `LabratoryDetails` created from `ISO.LabratoryDetails.GetAllLabratoryDetails()`. Includes exception handling. --- ### `TestEngineerDetails` - **`TestEngineerDetails()`** Default constructor. Initializes `_testEngineerDetails` with a new `ISO.TestEngineerDetails`, setting `Name` to `"(none)"`. - **`TestEngineerDetails(ISO.TestEngineerDetails testEngineerDetails)`** Copy constructor. Creates a new `ISO.TestEngineerDetails` instance from `testEngineerDetails`. - **`string Name { get; set; }`** Gets or sets the `Name` property of `_testEngineerDetails`. - **`ISO.TestEngineerDetails GetISOTestEngineer()`** Returns the internal `_testEngineerDetails` instance. - **`override string ToString()`** Returns the `Name` property. ### `TestEngineerDetailsList` - **`static TestEngineerDetailsList TestEngineerList { get; }`** Singleton accessor. - **`TestEngineerDetails[] TestEngineers { get; }`** Returns a sorted (by `Name`, using `CompareTo`) array of all `TestEngineerDetails`, including "(none)". Thread-safe via `lock` and lazy initialization. - **`TestEngineerDetails[] GetAllTestEngineers()`** Returns a fresh array containing a new "(none)" `TestEngineerDetails` followed by all `TestEngineerDetails` created from `ISO.TestEngineerDetails.GetAllTestEngineerDetails()`. - **`TestEngineerDetails GetTestEngineerDetail(string name)`** Returns the first `TestEngineerDetails` in `TestEngineers` (parallel LINQ query) matching `name`, or `null`. ## 3. Invariants - **"(none)" Placeholder**: Each list (`CustomerDetails`, `LabratoryDetails`, `TestEngineerDetails`) *always* includes a special entry with `Name == "(none)"` as the first element returned by `GetAll*()` methods. - **Deduplication**: The internal `_customers`, `_labs`, and `_testEngineers` dictionaries use `Name` as the key, ensuring only one entry per unique name (last one wins in case of duplicates in `GetAll*()`). - **Sorted Output**: The `Customers`, `Labs`, and `TestEngineers` properties return arrays sorted by `Name` using ordinal string comparison (`String.Compare(..., StringComparison.Ordinal)` or `CompareTo`). - **Thread Safety**: All list properties (`Customers`, `Labs`, `TestEngineers`) and their underlying population methods (`PopulateCustomers`, `PopulateList`, `PopulateEngineers`) are guarded by dedicated static `lock` objects. However, `GetCustomerDetail` and `GetTestEngineerDetail` use `AsParallel()` on the *already-computed* `Customers`/`TestEngineers` array, which is safe but not optimized. - **Null Handling**: `Compare*` methods explicitly handle `null` inputs (returning `-1`, `0`, or `1` as appropriate). `Get*Detail` methods return `null` if no match is found. ## 4. Dependencies - **Internal Dependencies**: - `ISO.CustomerDetails`, `ISO.LabratoryDetails`, `ISO.TestEngineerDetails` (from the `ISO` namespace) — core data types being wrapped. - `ISO.CustomerDetails.GetAllCustomerDetails()`, `ISO.LabratoryDetails.GetAllLabratoryDetails()`, `ISO.TestEngineerDetails.GetAllTestEngineerDetails()` — static methods to fetch raw data. - **External Dependencies**: - `DTS.Utilities.Logging.APILogger` (used in `LabratoryDetailsList` only) — for logging exceptions during lab retrieval. - Standard .NET: `System`, `System.Collections.Generic`, `System.Linq`. - **Depended Upon**: This module is part of `DatabaseExport` namespace and is likely consumed by higher-level export/reporting logic in the `DataPRO` system (not visible in source). ## 5. Gotchas - **Inconsistent Naming**: Class is named `LabratoryDetails` (misspelled) instead of `LaboratoryDetails`. This typo is propagated in both class and list names. - **Exception Swallowing**: `LabratoryDetailsList` silently swallows exceptions in `GetLab` and `GetAllLabs` (logs only via `APILogger`), which may hide failures during lab data loading. - **Race Condition in `Populate*`**: While `Populate*` methods are called under lock, they are not idempotent-safe in all cases: - `CustomerDetailsList.PopulateCustomers()` checks `if (null != _customers) return;` — safe. - `TestEngineerDetailsList.PopulateEngineers()` does *not* check `_testEngineers != null` before reassigning — safe only because it’s called under lock *and* only once. - `LabratoryDetailsList.PopulateList()` has the same safe guard (`if (null != _labs) return;`). → All are safe *in practice* due to locking, but the pattern is fragile. - **Redundant Copying**: Both constructors (`CustomerDetails(ISO.CustomerDetails)`, etc.) create a *new* instance of the underlying `ISO.*Details` (via copy constructor), not a reference wrapper. This is intentional but may be surprising if mutation of the returned `ISO.*Details` is expected to affect the wrapper’s internal state. - **Inconsistent `Get*Detail` Implementations**: - `CustomerDetailsList.GetCustomerDetail` and `TestEngineerDetailsList.GetTestEngineerDetail` use `AsParallel()` on the *already-computed* array — unnecessary overhead for small lists. - `LabratoryDetailsList.GetLab` uses direct dictionary lookup (`_labs.ContainsKey`) — more efficient, but only works *after* `Labs` property has been accessed (since `_labs` is populated in `Labs` getter, not eagerly). - **No Validation**: No validation on `Name` values (e.g., empty strings, duplicates in raw data) — relies on underlying `ISO.*` types or data source to prevent invalid names. - **Hardcoded Placeholder**: The `"(none)"` string is hardcoded in constructors. No constant or resource reference (despite commented-out `Strings.StringResources.TestTemplate_EmptyListName` in `TestEngineerDetails`).