GST Framework Guide
適用對象:新進開發人員、需要了解底層架構的工程師 前置知識:C#、.NET 8、MVVM Pattern 基礎 預計閱讀時間:60 分鐘(完整閱讀)/ 10 分鐘(快速開始) 最後更新:2026-01-18 版本:1.0.0
學習目標
完成本指南後,你將能夠:
- 理解 GST Framework 的分層架構和設計理念
- 知道各 Layer 的職責和模組組成
- 能夠在正確的位置新增功能或修改程式碼
- 了解 Plugin 系統的運作方式
- 遵循 GST 命名規範和開發標準
目錄
- 快速開始(10 分鐘)
- 架構總覽
- Core Layer 詳解
- Plugin Layer 詳解
- Protocols Layer 詳解
- UI Layer 詳解
- Application Layer 詳解
- 開發流程與規範
- 常見問題 FAQ
- 相關資源
1. 快速開始
1.1 專案結構一覽
D:\WorkSpace\GatherTech\Core\GST-develop\
├── src/
│ ├── Core/ # 核心層(穩定,少變動)
│ │ ├── GST.Core.Abstractions/ # Interface 定義
│ │ ├── GST.Core.Common/ # 共用工具
│ │ ├── GST.Core.Communication/ # 通訊抽象
│ │ ├── GST.Core.Configuration/ # 配置管理
│ │ ├── GST.Core.Logging/ # 日誌系統
│ │ └── GST.Core.Plugin/ # Plugin 載入器
│ │
│ ├── Plugins/ # Plugin 層(功能模組)
│ │ ├── GST.Plugin.Modbus/ # Modbus 通訊
│ │ ├── GST.Plugin.UserManagement/
│ │ ├── GST.Plugin.AuditTrail/
│ │ ├── GST.Plugin.Alarm/
│ │ └── ... (更多 Plugin)
│ │
│ ├── Protocols/ # 協定層(常數與模型)
│ │ └── GST.Protocols.SMB/ # SMB 設備協定
│ │
│ └── UI/ # UI 層
│ ├── GST.UI.Abstractions/ # UI 抽象
│ └── GST.UI.Wpf/ # WPF 支援
│
└── tests/ # 測試專案
└── GST.*.Tests/
1.2 第一個專案:引用 GST Framework
<!-- YourProject.csproj -->
<ItemGroup>
<!-- 必要:Core 抽象 -->
<ProjectReference Include="...\GST.Core.Abstractions\GST.Core.Abstractions.csproj" />
<!-- 選用:根據需求引用 -->
<ProjectReference Include="...\GST.Core.Common\GST.Core.Common.csproj" />
<ProjectReference Include="...\GST.Plugin.UserManagement\GST.Plugin.UserManagement.csproj" />
</ItemGroup>
1.3 DI 註冊範例
// Program.cs 或 App.xaml.cs
public void ConfigureServices(IServiceCollection services)
{
// Core 服務
services.AddGstLogging();
services.AddGstConfiguration();
// Plugin 服務
services.AddUserManagement(options =>
{
options.PasswordPolicy.MinLength = 8;
options.SessionTimeout = TimeSpan.FromMinutes(30);
});
services.AddAuditTrail(options =>
{
options.EnableHashChain = true;
});
}
2. 架構總覽
2.1 分層架構圖
┌─────────────────────────────────────────────────────────────────┐
│ Application Layer │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ GST.App.* │ │ Jope.* │ │ Leyu.* │ │
│ │ (通用應用) │ │ (喬璞專案) │ │ (樂宇專案) │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ UI Layer │
│ ┌─────────────────────────┐ ┌─────────────────────────────┐ │
│ │ GST.UI.Abstractions │ │ GST.UI.Wpf │ │
│ │ (UI 抽象) │ │ (WPF MVVM 支援) │ │
│ └─────────────────────────┘ └─────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 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 (常數、Enum、Specification、Model) │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
2.2 設計原則
| 原則 | 說明 |
|---|---|
| 依賴反轉 | 上層依賴抽象(Interface),不依賴具體實作 |
| 單一職責 | 每個 Module 只負責一件事 |
| 開放封閉 | 對擴展開放,對修改封閉(透過 Plugin 擴展) |
| 介面隔離 | Interface 小而專一,避免胖介面 |
2.3 專案命名規範
| 類型 | 格式 | 範例 |
|---|---|---|
| Framework 核心 | GST.Core.{Module} | GST.Core.Abstractions |
| Framework Plugin | GST.Plugin.{Feature} | GST.Plugin.UserManagement |
| Framework UI | GST.UI.{Technology} | GST.UI.Wpf |
| 協定定義 | GST.Protocols.{Domain} | GST.Protocols.SMB |
| 通用應用 | GST.App.{ProjectName} | GST.App.ProcessVision |
| 公司專屬 | {Company}.{ProjectName} | Jope.SMB.Core |
3. Core Layer 詳解
位置:
D:\WorkSpace\GatherTech\Core\GST-develop\src\Core\
Core Layer 是整個 Framework 的基石,提供所有 Interface 定義和基礎設施。
3.1 GST.Core.Abstractions
用途:定義所有 Interface,是唯一被所有專案引用的模組。
GST.Core.Abstractions/
├── Communication/
│ ├── ICommunicationChannel.cs # 通訊 Channel 抽象
│ ├── ITransport.cs # 傳輸層抽象
│ ├── ICommandQueue.cs # 命令佇列
│ └── IProtocol.cs # 協定抽象
├── Services/
│ ├── IUserService.cs # 使用者服務
│ ├── IAuditTrailService.cs # Audit Trail 服務
│ └── IAlarmService.cs # 警報服務
└── ...
設計原則:
- 只定義 Interface,不包含實作
- 不依賴任何其他專案(零依賴)
- 變動頻率最低
3.2 GST.Core.Communication
用途:提供通訊抽象,支援重試、熔斷、自動重連。
// ICommunicationChannel 使用範例
public class MyDevice
{
private readonly ICommunicationChannel _channel;
public async Task SendCommandAsync(byte[] command)
{
// 自動處理:重試、熔斷、佇列
var response = await _channel.Transport.SendAndReceiveAsync(command);
}
}
主要元件:
| 元件 | 職責 |
|---|---|
ITransport | 傳輸層(Serial、TCP、UDP) |
ICommandQueue | 命令優先級佇列 |
ICommunicationChannel | 整合 Transport + Queue + 重試 |
3.3 GST.Core.Common
用途:共用工具類別,提供跨模組共用的基礎功能。
GST.Core.Common/
├── Caching/ # 快取服務
│ ├── MemoryCacheService.cs # 記憶體快取實作
│ └── DefaultCacheKeyGenerator.cs
├── Exceptions/ # 自訂異常
│ ├── GstException.cs # 基礎異常類別
│ ├── CommunicationException.cs
│ ├── ConfigurationException.cs
│ └── PermissionException.cs
├── Extensions/ # 擴展方法
│ ├── StringExtensions.cs
│ ├── TaskExtensions.cs
│ └── CollectionExtensions.cs
├── Guards/ # 參數驗證
│ └── Guard.cs
├── Helpers/ # 工具類別
│ ├── AsyncLock.cs # 非同步鎖
│ ├── RetryHelper.cs # 重試機制
│ ├── DisposableHelper.cs
│ └── SingleInstanceGuard.cs # 單一執行個體保護
├── Results/ # Result Pattern
│ ├── Result.cs # 操作結果封裝
│ ├── Error.cs # 錯誤定義
│ └── LocalizableError.cs # 可本地化錯誤
└── TimeSync/ # NTP 時間同步(FDA Part 11)
├── NtpTimeSyncService.cs # NTP 同步服務
├── TimeSyncHostedService.cs
└── TimeSyncOptions.cs
Result Pattern 使用範例:
// 服務方法返回 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;
}
// 呼叫端處理
var result = await userService.GetUserByIdAsync(userId);
if (result.IsSuccess)
{
var user = result.Value;
// 處理成功情況
}
else
{
var error = result.Error;
// 處理錯誤情況
}
3.4 GST.Core.Configuration
用途:配置管理,支援 JSON、環境變數、命令列參數。
DI 註冊:
services.AddGstConfiguration(options =>
{
options.AddJsonFile("appsettings.json");
options.AddEnvironmentVariables();
});
3.5 GST.Core.Logging
用途:日誌系統,基於 Serilog,支援結構化日誌。
DI 註冊:
services.AddGstLogging(options =>
{
options.MinimumLevel = LogLevel.Information;
options.EnableConsole = true;
options.EnableFile = true;
options.LogPath = "logs/app.log";
});
3.6 GST.Core.Plugin
用途:Plugin 動態載入機制,支援熱插拔。
主要元件:
| 元件 | 職責 |
|---|---|
IPlugin | Plugin 介面定義 |
PluginLoader | 動態載入 Plugin DLL |
PluginOptions | 載入選項配置 |
DI 註冊:
services.AddGstPlugins(options =>
{
options.PluginPath = "plugins/";
options.IsParallelLoadingEnabled = false; // 預設循序載入
});
4. Plugin Layer 詳解
位置:
D:\WorkSpace\GatherTech\Core\GST-develop\src\Plugins\
Plugin Layer 提供可插拔的功能模組。
4.1 Plugin 清單
| Plugin | 用途 | FDA Part 11 |
|---|---|---|
GST.Plugin.Modbus | Modbus RTU/TCP 通訊 | - |
GST.Plugin.UserManagement | 使用者帳號管理 | ✅ |
GST.Plugin.AuditTrail | 操作記錄追蹤 | ✅ |
GST.Plugin.ElectronicSignature | 電子簽章 | ✅ |
GST.Plugin.Alarm | 警報管理 | - |
GST.Plugin.Localization | 多國語言 | - |
GST.Plugin.Export | 資料匯出 | - |
GST.Plugin.FileStorage | 檔案儲存(Hash Chain) | ✅ |
GST.Plugin.TimeSync | NTP 時間同步 | ✅ |
GST.Plugin.SessionIdle | 閒置自動登出 | ✅ |
4.2 Plugin 使用範例
// DI 註冊
services.AddUserManagement(options =>
{
options.PasswordPolicy.MinLength = 8;
options.PasswordPolicy.RequireUppercase = true;
options.PasswordPolicy.HistoryCount = 5;
});
// 使用服務
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 合規)
用途:操作記錄追蹤,支援 Hash Chain 完整性驗證。
主要介面:
public interface IAuditService
{
// 記錄使用者操作
Task LogUserActionAsync(
AuditAction action,
string description,
string? entityType = null,
string? entityId = null,
object? metadata = null,
CancellationToken cancellationToken = default);
// 記錄資料變更(含新舊值)
Task LogDataChangeAsync(
AuditAction action,
string entityType,
string entityId,
string description,
object? oldValues = null,
object? newValues = null,
CancellationToken cancellationToken = default);
// 記錄系統事件
Task LogSystemEventAsync(
AuditAction action,
string description,
AuditResult result = AuditResult.Success,
object? metadata = null,
CancellationToken cancellationToken = default);
// 查詢 Audit 記錄
Task<IReadOnlyList<AuditEntry>> QueryAsync(
AuditQueryOptions options,
CancellationToken cancellationToken = default);
// 匯出 Audit 記錄
Task<byte[]> ExportToCsvAsync(AuditQueryOptions options, CancellationToken ct = default);
Task<byte[]> ExportToExcelAsync(AuditQueryOptions options, CancellationToken ct = default);
// FDA 合規:歸檔而非刪除
Task<int> ArchiveAsync(DateTime olderThan, string archivePath, CancellationToken ct = default);
}
DI 註冊:
services.AddAuditTrail(options =>
{
options.EnableHashChain = true; // 啟用 Hash Chain
options.ShouldPreventDeletion = true; // 禁止刪除(FDA 合規)
options.RetentionDays = 365 * 7; // 保留 7 年
});
使用範例:
public class RecipeService
{
private readonly IAuditService _auditService;
public async Task UpdateRecipeAsync(Recipe recipe, Recipe oldRecipe)
{
// 更新邏輯...
// 記錄變更
await _auditService.LogDataChangeAsync(
AuditAction.Update,
entityType: "Recipe",
entityId: recipe.Id.ToString(),
description: "Recipe parameters updated",
oldValues: oldRecipe,
newValues: recipe);
}
}
4.4 其他 FDA Part 11 Plugin
| Plugin | 用途 | 關鍵功能 |
|---|---|---|
GST.Plugin.UserManagement | 帳號管理 | 密碼策略、密碼歷史、帳號鎖定 |
GST.Plugin.ElectronicSignature | 電子簽章 | 雙重驗證、簽章圖片儲存 |
GST.Core.FileStorage | 檔案儲存 | Hash Chain、WAL Buffer |
GST.Core.Common.TimeSync | 時間同步 | NTP 同步、時間偏移監控 |
5. Protocols Layer 詳解
位置:
D:\WorkSpace\GatherTech\Core\GST-develop\src\Protocols\
Protocols Layer 定義設備通訊協定的常數和模型。
5.1 設計原則
重要:僅共用常數和模型,不共用編碼/解碼邏輯。
App 和 Simulator 的關係:
┌─────────────────┐ ┌─────────────────┐
│ App (Master) │ 通訊 │ Simulator (Slave)│
│ 獨立實作協定 │ ←────→ │ 獨立實作協定 │
└─────────────────┘ └─────────────────┘
│ │
└───── 交叉驗證正確性 ───────┘
| 類別 | 是否共用 | 原因 |
|---|---|---|
| 協定常數 (STX, ETX, PFC) | ✅ 共用 | 純定義 |
| 設備 ID | ✅ 共用 | 純常數 |
| 資料模型 | ✅ 共用 | 純資料結構 |
| 編碼邏輯 | ❌ 不共用 | 需獨立實作驗證 |
| 解碼邏輯 | ❌ 不共用 | 需獨立實作驗證 |
5.2 GST.Protocols.SMB
GST.Protocols.SMB/
├── Constants/
│ ├── ControlCharacters.cs # STX, ETX, ACK, NACK
│ ├── DeviceAddresses.cs # 設備地址
│ ├── HanvonPumpCodes.cs # NP7000 PFC 碼
│ ├── HanvonDetectorCodes.cs # NU3000/UV1000D PFC 碼
│ ├── SksValveCodes.cs # S3612/S3203 協定常數
│ └── EppCodes.cs # EPP 協定常數
├── Enums/
│ ├── PumpRunState.cs
│ ├── ValvePosition.cs
│ └── ...
├── Specifications/
│ ├── NP7000Spec.cs # 流量/壓力規格
│ └── ...
└── Models/
├── PumpStatus.cs
├── DetectorStatus.cs
└── ...
6. UI Layer 詳解
位置:
D:\WorkSpace\GatherTech\Core\GST-develop\src\UI\
6.1 GST.UI.Abstractions
用途:UI 層的 Interface 定義,提供框架無關的 UI 抽象。
GST.UI.Abstractions/
├── Commands/
│ ├── IRelayCommand.cs # 命令介面
│ ├── AsyncRelayCommand.cs # 非同步命令
│ └── RelayCommand.cs # 同步命令
├── Services/
│ ├── IDialogService.cs # 對話框服務
│ ├── INavigationService.cs # 導航服務
│ └── IMessageBus.cs # 訊息匯流排
├── ViewModels/
│ ├── IViewModel.cs # ViewModel 介面
│ ├── ViewModelBase.cs # ViewModel 基類
│ └── IDialogViewModel.cs # 對話框 ViewModel
└── Views/
├── IView.cs # View 介面
└── IDialogView.cs # 對話框 View
6.2 GST.UI.Wpf
用途:WPF MVVM 支援,提供 WPF 專屬實作。
主要元件:
| 元件 | 用途 |
|---|---|
WpfViewModelBase | 支援 Dispatcher 的 ViewModel 基類 |
WpfDialogViewModelBase | 對話框 ViewModel 基類 |
WpfDialogService | WPF 對話框服務實作 |
LocalizeExtension | XAML 本地化標記擴展 |
WpfViewModelBase 使用範例:
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();
// 自動在 UI Thread 更新
StatusMessage = $"Loaded {data.Count} items";
}
finally
{
IsBusy = false;
}
}
// 需要明確在 UI Thread 執行時
protected void UpdateUI(Action action)
{
InvokeOnUIThread(action);
}
}
本地化擴展使用範例:
<!-- XAML -->
<Button Content="{l:Localize Save}" />
<TextBlock Text="{l:Localize Errors.Required}" />
常用 Converter:
| Converter | 用途 |
|---|---|
BooleanToVisibilityConverter | bool → Visibility |
InverseBooleanConverter | bool 反轉 |
NullToVisibilityConverter | null → Collapsed |
7. Application Layer 詳解
7.1 專案類型
| 類型 | 命名格式 | 範例 |
|---|---|---|
| 通用應用 | GST.App.{Name} | GST.App.ProcessVision |
| 喬璞專案 | Jope.{Name} | Jope.SMB.Core, Jope.SMB.WPF |
| 樂宇專案 | Leyu.{Name} | Leyu.Equipment.Control |
7.2 應用層結構範例
Jope.SMB.App/
├── src/
│ ├── Jope.SMB.Core/ # 業務邏輯
│ │ ├── Devices/ # 設備控制
│ │ ├── Control/ # 控制邏輯
│ │ └── Services/ # 服務
│ └── Jope.SMB.WPF/ # WPF UI
│ ├── ViewModels/
│ ├── Views/
│ └── Converters/
└── tests/
└── Jope.SMB.Core.Tests/
8. 開發流程與規範
8.1 必讀文件
| 文件 | 位置 |
|---|---|
| 共用規範 | D:\WorkSpace\GatherTech\PM\docs\shared\agent-rules\COMMON-RULES.md |
| 命名規範 | D:\WorkSpace\GatherTech\PM\docs\shared\GST-CSharp-Naming-Conventions.md |
8.2 命名規範速查
| 類型 | 格式 | 範例 |
|---|---|---|
| Interface | I{Name} | IUserService |
| Private Field | _camelCase | _userRepository |
| Async Method | {Name}Async | GetUserByIdAsync |
| Boolean Property | Is/Has/Can/Should | IsConnected |
8.3 Git 分支策略
main ─────────────────────────────────────────────►
│
└── develop ───────────────────────────────►
│
├── feature/gst-xx-description ──►
│
└── feature/jop-xx-description ──►
8.4 Commit Message 格式
<type>(<scope>): <subject> (ref <issue-id>)
type: feat, fix, docs, style, refactor, perf, test, chore
scope: 模組名稱
subject: 簡短說明
issue-id: Linear Issue ID
範例:
feat(communication): add ICommunicationChannel interface (ref GST-72)
fix(pump): resolve timeout issue in SendCommandAsync (ref JOP-59)
9. 常見問題 FAQ
Q1: 新功能應該放在哪一層?
A: 依據功能性質:
- 通用基礎功能 → Core Layer
- 可插拔功能模組 → Plugin Layer
- 設備協定常數 → Protocols Layer
- 應用專屬功能 → Application Layer
Q2: 如何新增一個 Plugin?
A:
- 在
src/Plugins/建立GST.Plugin.{Name}專案 - 實作 Interface(定義在 Abstractions)
- 提供
Add{Name}擴充方法供 DI 註冊 - 撰寫單元測試
Q3: 編碼/解碼邏輯為什麼不放在 Protocols Layer?
A: 為了保持 Simulator 的交叉驗證價值。如果 App 和 Simulator 共用編碼/解碼邏輯,當邏輯有 bug 時兩邊都會有相同的錯誤,無法透過測試發現問題。
Q4: 如何處理 FDA Part 11 合規需求?
A: 使用標記為 FDA Part 11 的 Plugin:
GST.Plugin.UserManagement- 帳號管理GST.Plugin.AuditTrail- 操作追蹤GST.Plugin.ElectronicSignature- 電子簽章GST.Plugin.FileStorage- Hash Chain 儲存
10. 相關資源
文件連結
| 文件 | 位置 |
|---|---|
| 共用規範 | D:\WorkSpace\GatherTech\PM\docs\shared\agent-rules\COMMON-RULES.md |
| 命名規範 | D:\WorkSpace\GatherTech\PM\docs\shared\GST-CSharp-Naming-Conventions.md |
| Multi-Agent 指南 | D:\WorkSpace\GatherTech\PM\docs\shared\GST-MULTI-AGENT-GUIDE.md |
專案位置
| 專案 | 位置 |
|---|---|
| GST Framework | D:\WorkSpace\GatherTech\Core\GST-develop\ |
| Jope.SMB.App | D:\WorkSpace\GatherTech\喬璞科技\Jope.SMB.App\ |
| GST.Simulator | D:\WorkSpace\GatherTech\Core\Simulator\GST.Simulator\ |
Linear 文件
下一步
- 深入了解特定模組:閱讀各 Plugin 的 README 或原始碼
- 實作練習:嘗試建立一個簡單的應用程式
- 參與開發:查看 Linear Issues,挑選適合的任務
版本歷史
| 版本 | 日期 | 變更 |
|---|---|---|
| 1.0.0 | 2026-01-18 | 初版建立 |
| 1.1.0 | 2026-01-18 | GST-19 審查後補充:Core.Common、AuditTrail、UI.Wpf 詳細說明 |