






















在实际工程中,我们经常需要构建工具型程序:
一开始,最自然的做法是:
👉 使用 Command Pattern(命令模式)自行实现一套 CLI 调度系统
这在架构上是完全正确的。
但当命令逐渐增多、参数变复杂之后,你会发现:
我们并不是在实现“业务命令”,
而是在不断重复造一个 命令行解析框架。
这正是 System.CommandLine 存在的意义。
典型的手写方案通常长这样:
- ICommand
- CommandGenerate
- CommandParse
- CommandExport
- Program.cs 中手动解析 args
- switch / dictionary 做 dispatch
--help / usage 要自己维护问题不在设计,而在“你做了太多框架层的工作”。
一句话定义:
System.CommandLine 是微软官方提供的、
基于 Command Pattern 的命令行应用框架
它做的事情只有一件:
把“命令行解析 + 路由”这层脏活累活标准化
而你只需要关心:
很多人误解 System.CommandLine 是“替代 Command 模式”。
实际上正好相反:
System.CommandLine 是 Command 模式在 CLI 场景下的成熟实现
你之前的设计思想是对的,只是:
一个工程级 CLI 工具,我推荐这样的结构:
ProjectRoot
│
├── Program.cs // CLI 装配层
│
├── Commands/ // 命令定义层
│ ├── GenerateCommand.cs
│ ├── ParseCommand.cs
│ └── ExportCommand.cs
│
├── Services/ // 核心业务
│ ├── Generator.cs
│ ├── Parser.cs
│ └── Exporter.cs
│
└── Infrastructure/
└── PathResolver.cs
👉 Command 层不写业务,只表达“意图”
using System.CommandLine;
var root = new RootCommand("Sample CLI Tool");
root.AddCommand(GenerateCommand.Build());
root.AddCommand(ParseCommand.Build());
return await root.InvokeAsync(args);
没有 switch,没有 if,没有手写解析。
using System.CommandLine;
public static class GenerateCommand
{
public static Command Build()
{
var command = new Command(
"generate",
"Generate output from input data"
);
var input = new Option<string>(
"--input",
description: "Input file path"
) { IsRequired = true };
var output = new Option<string>(
"--output",
description: "Output file path"
) { IsRequired = true };
command.AddOption(input);
command.AddOption(output);
command.SetHandler((string i, string o) =>
{
Console.WriteLine($"Generate: {i} -> {o}");
// Generator.Run(i, o);
}, input, output);
return command;
}
}
不需要你写任何额外代码,就已经支持:
tool generate --input data.json --output result.bin
tool generate --help
tool --help
包括:
在实际项目中,路径处理是高频需求。
推荐做法是:
public static class PathResolver
{
public static string Resolve(string path, bool relative)
{
return relative
? Path.GetFullPath(path)
: path;
}
}
Command 里只做:
var relative = new Option<bool>("--relative", "Use relative path");
👉 这样命令层保持干净,后续也方便迁移到 GUI / Editor 工具。
| 维度 | 手写 Command | System.CommandLine |
|---|---|---|
这不是推翻重来,而是自然升级。
System.CommandLine 非常适合:
如果你发现自己正在:
“为了 CLI 写大量非业务代码”
那就是一个明确的信号:
👉 该用它了。
命令模式本身没有问题,
问题在于:你不该在每个项目里重复造轮子。
System.CommandLine 做的不是“帮你偷懒”,
而是把精力从框架层解放出来,让你专注真正重要的事。\
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。