This module provides infrastructure for processing template files (.tmt files) used in test configuration and reporting workflows. It enables programmatic substitution of predefined placeholders (e.g., {NAME OF PROGRAM}, {{CHANNEL {0} NAME}}) with runtime values. The module decouples template structure from data population, supporting both global metadata (e.g., test ID, serial number) and per-channel properties (e.g., hardware channel number, scaling factors). It is part of the DTS.Common.Classes.TMAT namespace and serves as a foundational component for generating or modifying test configuration files dynamically.
2. Public Interface
Enums
TMTGlobalKeys
Enumerates global placeholder keys used in templates. Each member is decorated with a [TMTKey] attribute specifying the literal pattern to search for.
Examples:
NameOfProgram → pattern: "{NAME OF PROGRAM}"
DASSerialNumber → pattern: "{DAS SERIAL NUMBER}"
UdpStreamTimeChannelId → pattern: "{UDP STREAM TIME CHANNEL ID}"
TMTChannelKeys
Enumerates per-channel placeholder keys. Each pattern includes a format specifier {0} for the channel number.
Examples:
public string Key { get; }– Stores the literal pattern string (e.g., "{NAME OF PROGRAM}").
public TMTKey(string key)– Constructor initializing Key.
public static string GetKey(TMTGlobalKeys key)– Returns the pattern string for a global key.
public static string GetKey(TMTChannelKeys key, int channelNumber)– Returns the pattern string for a channel key, with {0} replaced by channelNumber.
Interface
ITMTTemplate
void UpdateValue(TMTGlobalKeys key, string value)
Replaces all occurrences of the pattern associated with key in the template with value.
void UpdateValue(TMTChannelKeys key, string value, int channelNumber)
Replaces all occurrences of the pattern associated with key (formatted with channelNumber) in the template with value.
string[] GetAllLines()
Returns the current content of the template as an array of lines.
Class
TMTTemplate : ITMTTemplate
public TMTTemplate(string templateLocation)
Loads all lines from the file at templateLocation into internal storage.
public TMTTemplate(string[] lines)
Initializes the template with the provided lines (e.g., for in-memory templates).
public void UpdateValue(TMTGlobalKeys key, string value)
Iterates through all lines; for each line containing the pattern for key, replaces the pattern with value.
public void UpdateValue(TMTChannelKeys key, string value, int channelNumber)
Iterates through all lines; for each line containing the formatted pattern for key (with channelNumber), replaces the pattern with value.
public string[] GetAllLines()
Returns a copy of the internal line list as an array.
3. Invariants
Template file existence is not enforced at construction: If templateLocation is invalid or the file does not exist, _allLines remains empty (no exception thrown).
Pattern replacement is literal and non-semantic:
Contains(pattern) is used for matching, so partial matches (e.g., "{NAME OF PROGRA}" inside "{NAME OF PROGRAM}") may cause unintended replacements.
Replacements are done via string.Replace, which replaces all occurrences of the pattern in a line (not just the first).
Channel keys require exact formatting: The pattern for channel keys includes double braces ({{...}}) to support string.Format, but the module does not validate that channelNumber produces a syntactically valid pattern (e.g., negative numbers are allowed).
No deduplication or ordering guarantees: Multiple updates to the same key in a single line will overwrite each other in sequence, but the final state depends on line order and replacement count.
4. Dependencies
Internal dependencies:
System.Collections.Generic (for List<string>)
System.IO (for File.Exists, File.ReadAllLines)
Reflection (System.Type.GetMember, Attribute.GetCustomAttribute) for pattern extraction from enums.
External dependencies:
Consumers must provide valid .tmt template files (or line arrays) to TMTTemplate constructors.
The module is used by other components (e.g., test execution or reporting systems) that populate template values.
No external libraries or services beyond core .NET types.
5. Gotchas
Case sensitivity: Pattern matching via Contains is case-sensitive. A template line " {NAME OF PROGRAM} " will match, but " {name of program} " will not.
Brace escaping in channel keys: The {{CHANNEL {0} ...}} pattern relies on string.Format semantics. If channelNumber is 0, the pattern becomes "{{CHANNEL 0 ...}}", which is correct. However, if channelNumber is negative (e.g., -1), the result is "{{CHANNEL -1 ...}}"—syntactically valid but semantically questionable.
No validation of placeholder presence: UpdateValue silently does nothing if the pattern is not found in any line.
No thread safety: The class is not thread-safe; concurrent calls to UpdateValue on the same instance may cause race conditions.
Memory overhead: All template lines are held in memory (_allLines) during processing. Large templates may consume significant memory.
No error handling for malformed templates: If a template line contains unbalanced braces or invalid string.Format syntax (e.g., {{CHANNEL {0} NAME), string.Format in GetKey(TMTChannelKeys, int) will throw an exception.
Historical quirk (commented):
UdpStreamTimeChannelId/UdpStreamDataChannelId and CreateDate were added in fixes FB 26736 and FB 29996, respectively—suggesting these keys were added post-initial design.