Skip to main content

GST Framework Guide

Target Audience: New developers, engineers who need to understand the underlying architecture Prerequisites: C#, .NET 8, MVVM Pattern fundamentals Estimated Reading Time: 60 minutes (full read) / 10 minutes (quick start) Last Updated: 2026-01-18 Version: 1.0.0


Learning Objectives

After completing this guide, you will be able to:

  • Understand the layered architecture and design philosophy of the GST Framework
  • Know the responsibilities and module composition of each layer
  • Add features or modify code in the correct location
  • Understand how the Plugin system works
  • Follow GST naming conventions and development standards

Table of Contents

  1. Quick Start (10 minutes)
  2. Architecture Overview
  3. Core Layer Details
  4. Plugin Layer Details
  5. Protocols Layer Details
  6. UI Layer Details
  7. Application Layer Details
  8. Development Workflow & Standards
  9. FAQ
  10. Related Resources

1. Quick Start

1.1 Project Structure Overview

D:\WorkSpace\GatherTech\Core\GST-develop\
├── src/
│ ├── Core/ # Core Layer (stable, rarely changed)
│ │ ├── GST.Core.Abstractions/ # Interface definitions
│ │ ├── GST.Core.Common/ # Shared utilities
│ │ ├── GST.Core.Communication/ # Communication abstractions
│ │ ├── GST.Core.Configuration/ # Configuration management
│ │ ├── GST.Core.Logging/ # Logging system
│ │ └── GST.Core.Plugin/ # Plugin loader
│ │
│ ├── Plugins/ # Plugin Layer (feature modules)
│ │ ├── GST.Plugin.Modbus/ # Modbus communication
│ │ ├── GST.Plugin.UserManagement/
│ │ ├── GST.Plugin.AuditTrail/
│ │ ├── GST.Plugin.Alarm/
│ │ └── ... (more Plugins)
│ │
│ ├── Protocols/ # Protocols Layer (constants & models)
│ │ └── GST.Protocols.SMB/ # SMB device protocol
│ │
│ └── UI/ # UI Layer
│ ├── GST.UI.Abstractions/ # UI abstractions
│ └── GST.UI.Wpf/ # WPF support

└── tests/ # Test projects
└── GST.*.Tests/

1.2 First Project: Referencing the GST Framework

<!-- YourProject.csproj -->
<ItemGroup>
<!-- Required: Core abstractions -->
<ProjectReference Include="...\GST.Core.Abstractions\GST.Core.Abstractions.csproj" />

<!-- Optional: reference as needed -->
<ProjectReference Include="...\GST.Core.Common\GST.Core.Common.csproj" />
<ProjectReference Include="...\GST.Plugin.UserManagement\GST.Plugin.UserManagement.csproj" />
</ItemGroup>

1.3 DI Registration Example

// Program.cs or App.xaml.cs
public void ConfigureServices(IServiceCollection services)
{
// Core services
services.AddGstLogging();
services.AddGstConfiguration();

// Plugin services
services.AddUserManagement(options =>
{
options.PasswordPolicy.MinLength = 8;
options.SessionTimeout = TimeSpan.FromMinutes(30);
});

services.AddAuditTrail(options =>
{
options.EnableHashChain = true;
});
}

2. Architecture Overview

2.1 Layered Architecture Diagram

┌─────────────────────────────────────────────────────────────────┐
│ Application Layer │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ GST.App.* │ │ Jope.* │ │ Leyu.* │ │
│ │ (General Apps) │ │ (Jope Projects) │ │ (Leyu Projects) │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────┐
│ UI Layer │
│ ┌─────────────────────────┐ ┌─────────────────────────────┐ │
│ │ GST.UI.Abstractions │ │ GST.UI.Wpf │ │
│ │ (UI Abstractions) │ │ (WPF MVVM Support) │ │
│ └─────────────────────────┘ └─────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────┐
│ Plugin Layer │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Modbus │ │ User │ │ Audit │ │ Alarm │ ... │
│ │ Plugin │ │ Mgmt │ │ Trail │ │ Plugin │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────┐
│ Core Layer │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Abstractions │ │ Common │ │ Communication│ │
│ │ (Interface) │ │ (Utilities) │ │ (Transport) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Configuration│ │ Logging │ │ Plugin │ │
│ │ (Settings) │ │ (Serilog) │ │ (Loader) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────┐
│ Protocols Layer │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ GST.Protocols.SMB (Constants, Enums, Specifications, │ │
│ │ Models) │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘

2.2 Design Principles

PrincipleDescription
Dependency InversionUpper layers depend on abstractions (Interfaces), not concrete implementations
Single ResponsibilityEach module is responsible for one thing only
Open-ClosedOpen for extension, closed for modification (extended via Plugins)
Interface SegregationInterfaces are small and focused, avoiding fat interfaces

2.3 Project Naming Conventions

TypeFormatExample
Framework CoreGST.Core.{Module}GST.Core.Abstractions
Framework PluginGST.Plugin.{Feature}GST.Plugin.UserManagement
Framework UIGST.UI.{Technology}GST.UI.Wpf
Protocol DefinitionsGST.Protocols.{Domain}GST.Protocols.SMB
General ApplicationsGST.App.{ProjectName}GST.App.ProcessVision
Company-Specific{Company}.{ProjectName}Jope.SMB.Core

3. Core Layer Details

Location: D:\WorkSpace\GatherTech\Core\GST-develop\src\Core\

The Core Layer is the foundation of the entire Framework, providing all Interface definitions and infrastructure.

3.1 GST.Core.Abstractions

Purpose: Defines all Interfaces; the only module referenced by all projects.

GST.Core.Abstractions/
├── Communication/
│ ├── ICommunicationChannel.cs # Communication Channel abstraction
│ ├── ITransport.cs # Transport layer abstraction
│ ├── ICommandQueue.cs # Command queue
│ └── IProtocol.cs # Protocol abstraction
├── Services/
│ ├── IUserService.cs # User service
│ ├── IAuditTrailService.cs # Audit Trail service
│ └── IAlarmService.cs # Alarm service
└── ...

Design Principles:

  • Defines only Interfaces, contains no implementations
  • Does not depend on any other project (zero dependencies)
  • Lowest change frequency

3.2 GST.Core.Communication

Purpose: Provides communication abstractions with support for retry, circuit breaker, and automatic reconnection.

// ICommunicationChannel usage example
public class MyDevice
{
private readonly ICommunicationChannel _channel;

public async Task SendCommandAsync(byte[] command)
{
// Automatically handles: retry, circuit breaker, queuing
var response = await _channel.Transport.SendAndReceiveAsync(command);
}
}

Key Components:

ComponentResponsibility
ITransportTransport layer (Serial, TCP, UDP)
ICommandQueueCommand priority queue
ICommunicationChannelIntegrates Transport + Queue + Retry

3.3 GST.Core.Common

Purpose: Shared utility classes providing cross-module foundational functionality.

GST.Core.Common/
├── Caching/ # Cache service
│ ├── MemoryCacheService.cs # In-memory cache implementation
│ └── DefaultCacheKeyGenerator.cs
├── Exceptions/ # Custom exceptions
│ ├── GstException.cs # Base exception class
│ ├── CommunicationException.cs
│ ├── ConfigurationException.cs
│ └── PermissionException.cs
├── Extensions/ # Extension methods
│ ├── StringExtensions.cs
│ ├── TaskExtensions.cs
│ └── CollectionExtensions.cs
├── Guards/ # Parameter validation
│ └── Guard.cs
├── Helpers/ # Utility classes
│ ├── AsyncLock.cs # Async lock
│ ├── RetryHelper.cs # Retry mechanism
│ ├── DisposableHelper.cs
│ └── SingleInstanceGuard.cs # Single instance protection
├── Results/ # Result Pattern
│ ├── Result.cs # Operation result wrapper
│ ├── Error.cs # Error definition
│ └── LocalizableError.cs # Localizable error
└── TimeSync/ # NTP time synchronization (FDA Part 11)
├── NtpTimeSyncService.cs # NTP sync service
├── TimeSyncHostedService.cs
└── TimeSyncOptions.cs

Result Pattern Usage Example:

// Service method returning Result
public async Task<Result<User>> GetUserByIdAsync(Guid id)
{
var user = await _repository.FindAsync(id);
if (user is null)
return Error.NotFound("User.NotFound", $"User {id} not found");

return user;
}

// Caller handling
var result = await userService.GetUserByIdAsync(userId);
if (result.IsSuccess)
{
var user = result.Value;
// Handle success case
}
else
{
var error = result.Error;
// Handle error case
}

3.4 GST.Core.Configuration

Purpose: Configuration management, supporting JSON, environment variables, and command-line arguments.

DI Registration:

services.AddGstConfiguration(options =>
{
options.AddJsonFile("appsettings.json");
options.AddEnvironmentVariables();
});

3.5 GST.Core.Logging

Purpose: Logging system based on Serilog, supporting structured logging.

DI Registration:

services.AddGstLogging(options =>
{
options.MinimumLevel = LogLevel.Information;
options.EnableConsole = true;
options.EnableFile = true;
options.LogPath = "logs/app.log";
});

3.6 GST.Core.Plugin

Purpose: Plugin dynamic loading mechanism with hot-swap support.

Key Components:

ComponentResponsibility
IPluginPlugin interface definition
PluginLoaderDynamically loads Plugin DLLs
PluginOptionsLoading option configuration

DI Registration:

services.AddGstPlugins(options =>
{
options.PluginPath = "plugins/";
options.IsParallelLoadingEnabled = false; // Sequential loading by default
});

4. Plugin Layer Details

Location: D:\WorkSpace\GatherTech\Core\GST-develop\src\Plugins\

The Plugin Layer provides pluggable feature modules.

4.1 Plugin List

PluginPurposeFDA Part 11
GST.Plugin.ModbusModbus RTU/TCP communication-
GST.Plugin.UserManagementUser account management
GST.Plugin.AuditTrailOperation audit trail
GST.Plugin.ElectronicSignatureElectronic signature
GST.Plugin.AlarmAlarm management-
GST.Plugin.LocalizationMulti-language support-
GST.Plugin.ExportData export-
GST.Plugin.FileStorageFile storage (Hash Chain)
GST.Plugin.TimeSyncNTP time synchronization
GST.Plugin.SessionIdleIdle auto-logout

4.2 Plugin Usage Example

// DI Registration
services.AddUserManagement(options =>
{
options.PasswordPolicy.MinLength = 8;
options.PasswordPolicy.RequireUppercase = true;
options.PasswordPolicy.HistoryCount = 5;
});

// Using the service
public class LoginViewModel
{
private readonly IUserService _userService;

public async Task<bool> LoginAsync(string username, string password)
{
var result = await _userService.AuthenticateAsync(username, password);
return result.IsSuccess;
}
}

4.3 GST.Plugin.AuditTrail (FDA Part 11 Compliant)

Purpose: Operation audit trail with Hash Chain integrity verification.

Key Interface:

public interface IAuditService
{
// Log user actions
Task LogUserActionAsync(
AuditAction action,
string description,
string? entityType = null,
string? entityId = null,
object? metadata = null,
CancellationToken cancellationToken = default);

// Log data changes (with old/new values)
Task LogDataChangeAsync(
AuditAction action,
string entityType,
string entityId,
string description,
object? oldValues = null,
object? newValues = null,
CancellationToken cancellationToken = default);

// Log system events
Task LogSystemEventAsync(
AuditAction action,
string description,
AuditResult result = AuditResult.Success,
object? metadata = null,
CancellationToken cancellationToken = default);

// Query audit records
Task<IReadOnlyList<AuditEntry>> QueryAsync(
AuditQueryOptions options,
CancellationToken cancellationToken = default);

// Export audit records
Task<byte[]> ExportToCsvAsync(AuditQueryOptions options, CancellationToken ct = default);
Task<byte[]> ExportToExcelAsync(AuditQueryOptions options, CancellationToken ct = default);

// FDA compliant: archive instead of delete
Task<int> ArchiveAsync(DateTime olderThan, string archivePath, CancellationToken ct = default);
}

DI Registration:

services.AddAuditTrail(options =>
{
options.EnableHashChain = true; // Enable Hash Chain
options.ShouldPreventDeletion = true; // Prevent deletion (FDA compliant)
options.RetentionDays = 365 * 7; // Retain for 7 years
});

Usage Example:

public class RecipeService
{
private readonly IAuditService _auditService;

public async Task UpdateRecipeAsync(Recipe recipe, Recipe oldRecipe)
{
// Update logic...

// Log the change
await _auditService.LogDataChangeAsync(
AuditAction.Update,
entityType: "Recipe",
entityId: recipe.Id.ToString(),
description: "Recipe parameters updated",
oldValues: oldRecipe,
newValues: recipe);
}
}

4.4 Other FDA Part 11 Plugins

PluginPurposeKey Features
GST.Plugin.UserManagementAccount managementPassword policy, password history, account lockout
GST.Plugin.ElectronicSignatureElectronic signatureDual authentication, signature image storage
GST.Core.FileStorageFile storageHash Chain, WAL Buffer
GST.Core.Common.TimeSyncTime synchronizationNTP sync, time offset monitoring

5. Protocols Layer Details

Location: D:\WorkSpace\GatherTech\Core\GST-develop\src\Protocols\

The Protocols Layer defines device communication protocol constants and models.

5.1 Design Principles

Important: Only constants and models are shared; encoding/decoding logic is NOT shared.

Relationship between App and Simulator:
┌─────────────────┐ ┌─────────────────┐
│ App (Master) │ Comms │ Simulator (Slave)│
│ Implements │ ←────→ │ Implements │
│ protocol │ │ protocol │
│ independently │ │ independently │
└─────────────────┘ └─────────────────┘
│ │
└── Cross-validation of ────┘
correctness
CategoryShared?Reason
Protocol constants (STX, ETX, PFC)✅ SharedPure definitions
Device IDs✅ SharedPure constants
Data models✅ SharedPure data structures
Encoding logic❌ Not sharedRequires independent implementation for verification
Decoding logic❌ Not sharedRequires independent implementation for verification

5.2 GST.Protocols.SMB

GST.Protocols.SMB/
├── Constants/
│ ├── ControlCharacters.cs # STX, ETX, ACK, NACK
│ ├── DeviceAddresses.cs # Device addresses
│ ├── HanvonPumpCodes.cs # NP7000 PFC codes
│ ├── HanvonDetectorCodes.cs # NU3000/UV1000D PFC codes
│ ├── SksValveCodes.cs # S3612/S3203 protocol constants
│ └── EppCodes.cs # EPP protocol constants
├── Enums/
│ ├── PumpRunState.cs
│ ├── ValvePosition.cs
│ └── ...
├── Specifications/
│ ├── NP7000Spec.cs # Flow/pressure specifications
│ └── ...
└── Models/
├── PumpStatus.cs
├── DetectorStatus.cs
└── ...

6. UI Layer Details

Location: D:\WorkSpace\GatherTech\Core\GST-develop\src\UI\

6.1 GST.UI.Abstractions

Purpose: Interface definitions for the UI layer, providing framework-agnostic UI abstractions.

GST.UI.Abstractions/
├── Commands/
│ ├── IRelayCommand.cs # Command interface
│ ├── AsyncRelayCommand.cs # Async command
│ └── RelayCommand.cs # Sync command
├── Services/
│ ├── IDialogService.cs # Dialog service
│ ├── INavigationService.cs # Navigation service
│ └── IMessageBus.cs # Message bus
├── ViewModels/
│ ├── IViewModel.cs # ViewModel interface
│ ├── ViewModelBase.cs # ViewModel base class
│ └── IDialogViewModel.cs # Dialog ViewModel
└── Views/
├── IView.cs # View interface
└── IDialogView.cs # Dialog View

6.2 GST.UI.Wpf

Purpose: WPF MVVM support, providing WPF-specific implementations.

Key Components:

ComponentPurpose
WpfViewModelBaseViewModel base class with Dispatcher support
WpfDialogViewModelBaseDialog ViewModel base class
WpfDialogServiceWPF dialog service implementation
LocalizeExtensionXAML localization markup extension

WpfViewModelBase Usage Example:

public class MainViewModel : WpfViewModelBase
{
private string _statusMessage = string.Empty;

public string StatusMessage
{
get => _statusMessage;
set => SetProperty(ref _statusMessage, value);
}

public async Task LoadDataAsync()
{
IsBusy = true;
try
{
var data = await _dataService.GetDataAsync();

// Automatically updates on the UI thread
StatusMessage = $"Loaded {data.Count} items";
}
finally
{
IsBusy = false;
}
}

// When explicit UI thread execution is needed
protected void UpdateUI(Action action)
{
InvokeOnUIThread(action);
}
}

Localization Extension Usage Example:

<!-- XAML -->
<Button Content="{l:Localize Save}" />
<TextBlock Text="{l:Localize Errors.Required}" />

Common Converters:

ConverterPurpose
BooleanToVisibilityConverterbool → Visibility
InverseBooleanConverterbool inversion
NullToVisibilityConverternull → Collapsed

7. Application Layer Details

7.1 Project Types

TypeNaming FormatExample
General ApplicationsGST.App.{Name}GST.App.ProcessVision
Jope ProjectsJope.{Name}Jope.SMB.Core, Jope.SMB.WPF
Leyu ProjectsLeyu.{Name}Leyu.Equipment.Control

7.2 Application Layer Structure Example

Jope.SMB.App/
├── src/
│ ├── Jope.SMB.Core/ # Business logic
│ │ ├── Devices/ # Device control
│ │ ├── Control/ # Control logic
│ │ └── Services/ # Services
│ └── Jope.SMB.WPF/ # WPF UI
│ ├── ViewModels/
│ ├── Views/
│ └── Converters/
└── tests/
└── Jope.SMB.Core.Tests/

8. Development Workflow & Standards

8.1 Required Reading

DocumentLocation
Shared StandardsD:\WorkSpace\GatherTech\PM\docs\shared\agent-rules\COMMON-RULES.md
Naming ConventionsD:\WorkSpace\GatherTech\PM\docs\shared\GST-CSharp-Naming-Conventions.md

8.2 Naming Conventions Quick Reference

TypeFormatExample
InterfaceI{Name}IUserService
Private Field_camelCase_userRepository
Async Method{Name}AsyncGetUserByIdAsync
Boolean PropertyIs/Has/Can/ShouldIsConnected

8.3 Git Branching Strategy

main ─────────────────────────────────────────────►

└── develop ───────────────────────────────►

├── feature/gst-xx-description ──►

└── feature/jop-xx-description ──►

8.4 Commit Message Format

<type>(<scope>): <subject> (ref <issue-id>)

type: feat, fix, docs, style, refactor, perf, test, chore
scope: module name
subject: short description
issue-id: Linear Issue ID

Examples:

feat(communication): add ICommunicationChannel interface (ref GST-72)
fix(pump): resolve timeout issue in SendCommandAsync (ref JOP-59)

9. FAQ

Q1: Which layer should new features go in?

A: Based on the nature of the feature:

  • General foundational features → Core Layer
  • Pluggable feature modules → Plugin Layer
  • Device protocol constants → Protocols Layer
  • Application-specific features → Application Layer

Q2: How to add a new Plugin?

A:

  1. Create a GST.Plugin.{Name} project under src/Plugins/
  2. Implement the Interface (defined in Abstractions)
  3. Provide an Add{Name} extension method for DI registration
  4. Write unit tests

Q3: Why isn't encoding/decoding logic placed in the Protocols Layer?

A: To preserve the cross-validation value of the Simulator. If the App and Simulator share encoding/decoding logic, when there is a bug in the logic, both sides will have the same error, making it impossible to discover the issue through testing.

Q4: How to handle FDA Part 11 compliance requirements?

A: Use the Plugins marked as FDA Part 11:

  • GST.Plugin.UserManagement - Account management
  • GST.Plugin.AuditTrail - Operation tracking
  • GST.Plugin.ElectronicSignature - Electronic signature
  • GST.Plugin.FileStorage - Hash Chain storage

DocumentLocation
Shared StandardsD:\WorkSpace\GatherTech\PM\docs\shared\agent-rules\COMMON-RULES.md
Naming ConventionsD:\WorkSpace\GatherTech\PM\docs\shared\GST-CSharp-Naming-Conventions.md
Multi-Agent GuideD:\WorkSpace\GatherTech\PM\docs\shared\GST-MULTI-AGENT-GUIDE.md

Project Locations

ProjectLocation
GST FrameworkD:\WorkSpace\GatherTech\Core\GST-develop\
Jope.SMB.AppD:\WorkSpace\GatherTech\喬璞科技\Jope.SMB.App\
GST.SimulatorD:\WorkSpace\GatherTech\Core\Simulator\GST.Simulator\

Linear Documentation


Next Steps

  1. Deep dive into specific modules: Read the README or source code of each Plugin
  2. Hands-on practice: Try building a simple application
  3. Contribute: Check Linear Issues and pick a suitable task

Version History

VersionDateChanges
1.0.02026-01-18Initial creation
1.1.02026-01-18Post-GST-19 review additions: Core.Common, AuditTrail, UI.Wpf detailed descriptions