我最近遇到了我非常喜欢的 FubuCore 命令行解析实现,原因是:
- 它很容易使用 - 虽然我找不到它的文档,但 FubuCore 解决方案还提供了一个项目,其中包含一组很好的单元测试,这些测试比任何文档都更能说明功能
- 它有一个很好的面向对象设计,没有代码重复或我以前在命令行解析应用程序中遇到的其他类似情况
- 它是声明性的:您基本上为命令和参数集编写类,并用属性装饰它们以设置各种选项(例如名称、描述、强制/可选)
- 该库甚至会根据这些定义打印出漂亮的使用情况图表
下面是一个关于如何使用它的简单示例。为了说明用法,我编写了一个简单的实用程序,它有两个命令:
- 添加(将对象添加到列表中 - 对象由名称(字符串)、值(int)和布尔标志组成)
- list(列出所有当前添加的对象)
首先,我为'add'命令编写了一个Command类:
[Usage("add", "Adds an object to the list")]
[CommandDescription("Add object", Name = "add")]
public class AddCommand : FubuCommand<CommandInput>
{
public override bool Execute(CommandInput input)
{
State.Objects.Add(input); // add the new object to an in-memory collection
return true;
}
}
这个命令接受一个 CommandInput 实例作为参数,所以我定义下一个:
public class CommandInput
{
[RequiredUsage("add"), Description("The name of the object to add")]
public string ObjectName { get; set; }
[ValidUsage("add")]
[Description("The value of the object to add")]
public int ObjectValue { get; set; }
[Description("Multiply the value by -1")]
[ValidUsage("add")]
[FlagAlias("nv")]
public bool NegateValueFlag { get; set; }
}
下一个命令是'list',实现如下:
[Usage("list", "List the objects we have so far")]
[CommandDescription("List objects", Name = "list")]
public class ListCommand : FubuCommand<NullInput>
{
public override bool Execute(NullInput input)
{
State.Objects.ForEach(Console.WriteLine);
return false;
}
}
'list' 命令不带参数,所以我为此定义了一个 NullInput 类:
public class NullInput { }
现在剩下的就是将其连接到 Main() 方法中,如下所示:
static void Main(string[] args)
{
var factory = new CommandFactory();
factory.RegisterCommands(typeof(Program).Assembly);
var executor = new CommandExecutor(factory);
executor.Execute(args);
}
程序按预期工作,打印有关正确用法的提示,以防任何命令无效:
------------------------
Available commands:
------------------------
add -> Add object
list -> List objects
------------------------
以及“添加”命令的示例用法:
Usages for 'add' (Add object)
add <objectname> [-nv]
-------------------------------------------------
Arguments
-------------------------------------------------
objectname -> The name of the object to add
objectvalue -> The value of the object to add
-------------------------------------------------
-------------------------------------
Flags
-------------------------------------
[-nv] -> Multiply the value by -1
-------------------------------------