Skip to content

Parameter Parser

Reflection Emit edited this page May 20, 2018 · 7 revisions

Execution Groups

The parameters are grouped in execution groups. The execution groups are invoked sequentially depending on their group index (Higher group index means lower priority).
An execution group is marked active if one of its associated parameter is called. Only execution groups with an active status are invoked.
The class has to implement the IExecutionGroup interface and has to be decorated with the ExecutionGroupAttribute attribute.

    [ExecutionGroup("Installation", 2)]
    public sealed class InstallationExecutionGroup : IExecutionGroup
    {
    ...
        public void Execute(ParameterParser parser)
        {
        ...
        }
    }

Default Parameter

The default parameter is the default behaviour of the application if no parameter or an unknown set of values without a parameter key are passed to the program.
For example:

program.exe C:\temp\hello.txt

There are various ways of implementing the default parameter depending on the behaviour.

Default behaviour requires no values

ParameterParser.Execute

The ParameterParser.Execute method will return false if no execution group has been invoked. This can be used to invoke the default behaviour.

    if (!parser.Execute())
        DoAnyStuff();

ParameterAttribute

Adding an empty string to the parameter key set of the property will declare the parameter as a default parameter.

    [Parameter("Shows the help page", "help", "omg", "h", "")]
    public bool Help { get; private set; }

Default behaviour requires one or more values

ParameterAttribute

In the following code example the CountWordsInFile property's setter is invoked if the program is executed with or without the key.

program.exe C:\Windows\win.ini
program.exe -count C:\Windows\win.ini
    [Parameter("Counts the words in a file", "count-word", "count", "")]
    public string CountWordsInFile { get; private set; }

Required Parameter

Required parameters are parameters that has to be set if the associated execution group is marked active.

Optional Values

Optional values are parameters that can be called with or without a value. The program's behaviour can be different in each case.
For example:

program.exe -mode

The program could output the value of mode.

Mode is True

If the mode parameter is called with a value, then the program could set the value.

program.exe -mode false
Mode is False

Multiple Values In A Parameter

In some cases it is required that a parameter key has multiple values. For example:

program.exe -set hotdog food 66.90

Property Return Type As Array

If the parser detects an array in the property return type, it will split the values using space as delimeter.
Example:

    [Parameter("Sets the food category and price", "set", "S")]
    public string[] FoodCategoryAndPrice { get; private set; }

The resulting array is:

    FoodCategoryAndPrice[0] // hotdog
    FoodCategoryAndPrice[1] // food
    FoodCategoryAndPrice[2] // 66.90

Implicit / Explicit convertion

The parser uses the Cauldron.Cores Convert extension method which means that it will try to invoke the implicit or explicit operator if the proper parameters are found.
Example:

    public sealed class FoodCategoryPrice
    {
        public string Category { get; set; }
        public string Food { get; set; }
        public double Price { get; set; }

        public static explicit operator FoodCategoryPrice(string value)
        {
             var splittedValue = value.Split(' ');
             return new FoodCategoryPrice 
             { 
                 Food = splittedValue[0], 
                 Category = splittedValue[1], 
                 Price = splittedValue[2].ToDoubleUS() 
             };
        }
    }
    [Parameter("Sets the food category and price", "set", "S")]
    public FoodCategoryPrice FoodCategoryAndPrice { get; private set; }

Checking Parameters for Values

The Execute method provides the ParameterParser instance which can return all active parameters of the current execution group.

    public void Execute(ParameterParser parser)
    {
        var parameters = parser.GetActiveParameters(this);
        ...
    }

GetActiveParameters will return a list of property names of the active parameters. The parameters can be checked like following:

    if (parameters.Contains(nameof(PricesOf)))
    {
    }

It is also legitimate to check boolean parameters directly for true or false and a string for null or empty.

Exceptions

The parameter parser's execute method could raise the following exceptions:

  • RequiredParametersMissingException - Raised if the execution group is marked active and one of its required parameter is not set.
  • RequiredValuesMissingException - Raised if a parameter is called, but no value is passed.
  • UnknownParameterException - Raised if an unknown parameter is passed.

    The following is a typical implementation of the static Main Method.
    public static void Main(string[] args)
    {
        var parser = new ParameterParser(new MainExecutionGroup(), new InstallationExecutionGroup());
        parser.DescriptionColor = ConsoleColor.Cyan;

        try
        {
            parser.Parse(args);
            if (!parser.Execute())
                parser.ShowHelp();
        }
        catch (Exception e)
        {
           Console.ForegroundColor = ConsoleColor.Red;
           Console.WriteLine(e.Message);
        }
        finally
        {
            Console.ResetColor();
        }
    }

Parameter Description

The parameter description should contain usage explanation and usage examples. Examples and explanation typically starts with the program name and the involved parameter. Writing these strings directly in the description could lead to inconsistency if the parameter key or the program name is changed.
To encounter this problem the description has 4 tags that are replaced by the following:

$ux$ - Replaced by \n!!USAGE EXAMPLE: executableName -parameterKey
$mm$ - Replaced by \n!!executableName -parameterKey
$me$ - Replaced by executableName
$pm$ - Replaced by parameterKey

Example:

[Parameter("Creates a backup of the hosts file. Requires the full path of the back-up target directory.$mm$ [Directory]$ux$ C:\\Temp", "backup", "B")]

A description paragraph can be highlighted by adding !! at the beginning of the line.

[Parameter("Removes the scheduled task if exist.\n!!Be careful!", "remove-task", "R")]

Help Page

The help page is automatically shown if an exception is raised during execution.
An example of the help page:

Localization

The localization is based on Cauldron.Localization and it only requires an implementation of the ILocalizationSource interface. See Localization for more information.
The parser will automatically interprete the description in the ExecutionGroupAttribute and the ParameterAttribute as a key in the localization table.
In the following example the parser will look-up for the mainGroupDescription key in the dictionary and will output its value instead of the "mainGroupDescription" string.

[ExecutionGroup("mainGroupDescription")]
public class MainExecutionGroup
{
...
}

Same in this case. The parser will look-up for analyseFileDescription in the dictionary.

[Parameter("analyseFileDescription", "analyse", "A")]
public string AnalyseFile {get; set;}

The strings in the help page can be localized as well. The following keys has to be available in localization source otherwise only their keys are displayed.

  • application-name
  • version
  • description
  • product-name
  • publisher
  • usage-example
  • mandatory

Example