Recientemente me encontré con la implementación del análisis de la línea de comandos de FubuCore Me gusta mucho, las razones son:
- es fácil de usar, aunque no pude encontrar una documentación para ello, la solución FubuCore también proporciona un proyecto que contiene un buen conjunto de pruebas unitarias que hablan más sobre la funcionalidad que cualquier documentación.
- tiene un diseño agradable orientado a objetos, no tiene repetición de código u otras cosas que solía tener en mis aplicaciones de análisis de línea de comandos
- es declarativo: básicamente escribe clases para los Comandos y conjuntos de parámetros y los decora con atributos para establecer varias opciones (por ejemplo, nombre, descripción, obligatorio / opcional)
- la biblioteca incluso imprime un buen gráfico de uso, basado en estas definiciones
A continuación se muestra un ejemplo simple de cómo usar esto. Para ilustrar el uso, he escrito una utilidad simple que tiene dos comandos: - agregar (agrega un objeto a una lista - un objeto consiste en un nombre (cadena), valor (int) y una bandera booleana) - lista (listas todos los objetos agregados actualmente)
En primer lugar, escribí una clase de comando para el comando 'agregar':
[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;
}
}
Este comando toma una instancia de CommandInput como parámetro, así que lo defino a continuación:
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; }
}
El siguiente comando es 'list', que se implementa de la siguiente manera:
[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;
}
}
El comando 'list' no toma parámetros, por lo que definí una clase NullInput para esto:
public class NullInput { }
Todo lo que queda ahora es conectar esto en el método Main (), así:
static void Main(string[] args)
{
var factory = new CommandFactory();
factory.RegisterCommands(typeof(Program).Assembly);
var executor = new CommandExecutor(factory);
executor.Execute(args);
}
El programa funciona como se esperaba, imprimiendo pistas sobre el uso correcto en caso de que algún comando no sea válido:
------------------------
Available commands:
------------------------
add -> Add object
list -> List objects
------------------------
Y un uso de muestra para el comando 'agregar':
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
-------------------------------------