啟動參數解析器(命令列參數與環境變數自動映射)
一個強大的命令列參數和環境變數解析庫,支援將命令列參數和環境變數自動映射到強型別設定物件。
特性
- 參數優先級處理: 命令列參數 > 環境變數 > 預設值
- 泛型支援: 支援任意強型別設定類別
- 多種啟動方式相容: 支援 Docker、exe、shell 等啟動方式
- 自動前綴處理: 自動為參數新增
--前綴 - 布林參數支援: 支援多種布林參數格式
- 環境變數映射: 自動映射環境變數到設定屬性
- 型別轉換: 自動轉換字串參數到目標型別
- 特性支援: 支援豐富的設定特性
安裝
bash
dotnet add package GameFrameX.Foundation.Options快速開始
1. 定義設定類別
csharp
public class AppConfig
{
public string Host { get; set; } = "localhost";
public int Port { get; set; } = 8080;
public bool Debug { get; set; } = false;
public string LogLevel { get; set; } = "info";
public double Timeout { get; set; } = 30.5;
}2. 使用 OptionsBuilder
csharp
using GameFrameX.Foundation.Options;
class Program
{
static void Main(string[] args)
{
// 建立選項建構器
var builder = new OptionsBuilder<AppConfig>(args);
// 建構設定物件
var config = builder.Build();
// 使用設定
Console.WriteLine($"伺服器: {config.Host}:{config.Port}");
Console.WriteLine($"偵錯模式: {config.Debug}");
Console.WriteLine($"日誌級別: {config.LogLevel}");
Console.WriteLine($"逾時時間: {config.Timeout} 秒");
}
}詳細用法
命令列參數
支援多種參數格式:
bash
# 鍵值對格式
myapp.exe --host=example.com --port=9090 --debug=true
# 分離格式
myapp.exe --host example.com --port 9090 --debug true
# 布林旗標格式
myapp.exe --host example.com --port 9090 --debug
# 混合格式
myapp.exe --host=example.com --port 9090 --debug環境變數
bash
# 設定環境變數
export HOST=example.com
export PORT=9090
export DEBUG=true
# 執行程式
myapp.exeDocker 支援
dockerfile
# Dockerfile
FROM mcr.microsoft.com/dotnet/runtime:8.0
COPY . /app
WORKDIR /app
ENTRYPOINT ["dotnet", "MyApp.dll"]bash
# Docker 執行
docker run myapp --host example.com --port 9090 --debug
# 或使用環境變數
docker run -e HOST=example.com -e PORT=9090 -e DEBUG=true myapp進階用法
使用特性設定
csharp
using GameFrameX.Foundation.Options.Attributes;
public class AdvancedConfig
{
[Option("h", "host", Required = false, DefaultValue = "localhost")]
[HelpText("伺服器主機位址")]
public string Host { get; set; }
[Option("p", "port", Required = true)]
[HelpText("伺服器連接埠號")]
public int Port { get; set; }
[FlagOption("d", "debug")]
[HelpText("啟用偵錯模式")]
public bool Debug { get; set; }
[RequiredOption("api-key", Required = true)]
[EnvironmentVariable("API_KEY")]
[HelpText("API 金鑰")]
public string ApiKey { get; set; }
[DefaultValue(30.0)]
public double Timeout { get; set; }
}建構器選項
csharp
var builder = new OptionsBuilder<AppConfig>(
args: args,
boolFormat: BoolArgumentFormat.Flag, // 布林參數格式
ensurePrefixedKeys: true, // 確保參數有前綴
useEnvironmentVariables: true // 使用環境變數
);
var config = builder.Build(skipValidation: false); // 是否跳過驗證參數優先級
參數按以下優先級套用(高優先級覆蓋低優先級):
- 命令列參數 (最高優先級)
- 環境變數
- 預設值 (最低優先級)
範例
csharp
public class Config
{
public string Host { get; set; } = "localhost"; // 預設值
public int Port { get; set; } = 8080; // 預設值
}bash
# 設定環境變數
export HOST=env.example.com
export PORT=7070
# 執行程式(命令列參數覆蓋環境變數)
myapp.exe --host cmd.example.com
# 結果:
# Host = "cmd.example.com" (來自命令列參數)
# Port = 7070 (來自環境變數)布林參數處理
支援多種布林參數格式:
bash
# 旗標格式(建議)
myapp.exe --debug # debug = true
# 鍵值對格式
myapp.exe --debug=true # debug = true
myapp.exe --debug=false # debug = false
# 分離格式
myapp.exe --debug true # debug = true
myapp.exe --debug false # debug = false
# 支援的布林值
true, false, 1, 0, yes, no, on, off型別轉換
自動支援以下型別轉換:
string- 直接使用int,int?- 整數轉換bool,bool?- 布林值轉換double,double?- 雙精度浮點數轉換float,float?- 單精度浮點數轉換decimal,decimal?- 十進位數轉換DateTime,DateTime?- 日期時間轉換Guid,Guid?- GUID 轉換Enum- 列舉轉換
範例
csharp
public class TypedConfig
{
public int Port { get; set; }
public bool Debug { get; set; }
public DateTime StartTime { get; set; }
public LogLevel Level { get; set; } // 列舉
}
public enum LogLevel
{
Debug, Info, Warning, Error
}bash
myapp.exe --port 9090 --debug true --start-time "2024-01-01 10:00:00" --level Info錯誤處理
必要參數驗證
csharp
public class Config
{
[RequiredOption("api-key", Required = true)]
public string ApiKey { get; set; }
}如果缺少必要參數,會擲回 ArgumentException:
缺少必要的選項: api-key型別轉換錯誤
當參數值無法轉換為目標型別時,會使用預設值並在主控台輸出警告資訊。
偵錯模式
在開發過程中,可以透過啟用偵錯模式來檢視參數解析的詳細過程,便於排查設定問題。
最佳實踐
1. 設定類別設計
csharp
public class AppConfig
{
// 使用有意義的預設值
public string Host { get; set; } = "localhost";
public int Port { get; set; } = 8080;
// 布林屬性預設為 false
public bool Debug { get; set; } = false;
// 使用特性提供更多資訊
[RequiredOption("database-url", Required = true)]
[EnvironmentVariable("DATABASE_URL")]
public string DatabaseUrl { get; set; }
}2. 錯誤處理
csharp
try
{
var builder = new OptionsBuilder<AppConfig>(args);
var config = builder.Build();
// 使用設定啟動應用
StartApplication(config);
}
catch (ArgumentException ex)
{
Console.WriteLine($"設定錯誤: {ex.Message}");
Environment.Exit(1);
}3. Docker 整合
csharp
// Program.cs
public class Program
{
public static void Main(string[] args)
{
var builder = new OptionsBuilder<AppConfig>(args);
var config = builder.Build();
// 在 Docker 中,通常使用環境變數
// 在開發中,通常使用命令列參數
var app = CreateApplication(config);
app.Run();
}
}yaml
# docker-compose.yml
version: '3.8'
services:
myapp:
image: myapp:latest
environment:
- HOST=0.0.0.0
- PORT=8080
- DEBUG=false
command: ["--log-level", "info"]API 參考
OptionsBuilder<T>
| 方法 | 說明 |
|---|---|
OptionsBuilder<T>(args) | 建立建構器,傳入命令列參數 |
Build() | 建構設定物件 |
Build(skipValidation) | 建構設定物件,可選跳過驗證 |
特性 (Attributes)
| 特性 | 說明 |
|---|---|
[Option(shortName, longName)] | 設定選項映射 |
[FlagOption(shortName, longName)] | 布林旗標選項 |
[RequiredOption(longName)] | 必要選項 |
[EnvironmentVariable(name)] | 環境變數映射 |
[DefaultValue(value)] | 預設值 |
[HelpText(text)] | 說明文字描述 |
CommandLineArgumentConverter
CommandLineArgumentConverter 提供底層的命令列參數轉換功能,支援將字串參數轉換為目標型別。通常透過 OptionsBuilder 間接使用,無需直接呼叫。
完整範例
csharp
using GameFrameX.Foundation.Options;
using GameFrameX.Foundation.Options.Attributes;
namespace MyApp
{
public class ServerConfig
{
[Option("h", "host", DefaultValue = "localhost")]
[EnvironmentVariable("SERVER_HOST")]
[HelpText("伺服器主機位址")]
public string Host { get; set; }
[Option("p", "port", DefaultValue = 8080)]
[EnvironmentVariable("SERVER_PORT")]
[HelpText("伺服器連接埠號")]
public int Port { get; set; }
[FlagOption("d", "debug")]
[EnvironmentVariable("DEBUG")]
[HelpText("啟用偵錯模式")]
public bool Debug { get; set; }
[RequiredOption("database-url", Required = true)]
[EnvironmentVariable("DATABASE_URL")]
[HelpText("資料庫連線字串")]
public string DatabaseUrl { get; set; }
[Option("timeout", DefaultValue = 30.0)]
[EnvironmentVariable("REQUEST_TIMEOUT")]
[HelpText("請求逾時時間(秒)")]
public double Timeout { get; set; }
}
class Program
{
static void Main(string[] args)
{
try
{
var builder = new OptionsBuilder<ServerConfig>(args);
var config = builder.Build();
Console.WriteLine("伺服器設定:");
Console.WriteLine($" 主機: {config.Host}");
Console.WriteLine($" 連接埠: {config.Port}");
Console.WriteLine($" 偵錯: {config.Debug}");
Console.WriteLine($" 資料庫: {config.DatabaseUrl}");
Console.WriteLine($" 逾時: {config.Timeout} 秒");
// 啟動伺服器
StartServer(config);
}
catch (ArgumentException ex)
{
Console.WriteLine($"設定錯誤: {ex.Message}");
ShowHelp();
Environment.Exit(1);
}
}
static void StartServer(ServerConfig config)
{
// 伺服器啟動邏輯
Console.WriteLine($"伺服器啟動在 {config.Host}:{config.Port}");
}
static void ShowHelp()
{
Console.WriteLine("用法:");
Console.WriteLine(" myapp.exe --host <主機> --port <連接埠> --database-url <資料庫 URL> [選項]");
Console.WriteLine();
Console.WriteLine("選項:");
Console.WriteLine(" -h, --host <主機> 伺服器主機位址 (預設: localhost)");
Console.WriteLine(" -p, --port <連接埠> 伺服器連接埠號 (預設: 8080)");
Console.WriteLine(" -d, --debug 啟用偵錯模式");
Console.WriteLine(" --database-url <URL> 資料庫連線字串 (必要)");
Console.WriteLine(" --timeout <秒> 請求逾時時間 (預設: 30.0)");
}
}
}