Page 27 - MSDN Magazine, March 2019
P. 27

the System.CommandLine framework, they’re included automatically, without any effort on the part of the command-line interface developer. Delimiters: The association of an argument to a command or an option is done via a delimiter. Common delimiters are space, colon and the equal sign. For example, when specifying the verbosity of a dotnet build, you can use any of the following three variations: --verbosity=diagnostic, --verbosity diagnostic or --verbosity:diagnostic. Aliases: These are additional names that can be used to identify commands and options. For example, with dotnet, “classlib” is an
alias for “Class library” and -v is an alias for “--verbosity.”
Fortunately, the new System.CommandLine API provides a significant improvement on this simple scenario, and does so in a way I haven’t previously seen.
Prior to System.CommandLine, the lack of built-in parsing support meant that when your application launched, you as the developer had to analyze the array of arguments to determine which corresponded to which argument type, and then correctly associate all of the values together. While .NET includes numerous attempts at solving this problem, none has emerged as a default solution, and none scales well to support both simple and complex scenarios. With this in mind, System.CommandLine was developed and released in alpha form (see github.com/dotnet/command-line-api).
Keep Simple Things Simple
Imagine that you’re writing an image conversion program that converts an image file to a different format based on the output name specified. The command line could be something like this:
imageconv --input sunrise.CR2 --output sunrise.JPG
Given this command line (see “Passing Parameters to the .NET Core Executable” for alternative command-line syntax), the imageconv program will launch into the Main entry point, static void Main(string[] args), with a string array of four corresponding arguments. Unfortunately, there’s no association between --input and sunrise.CR2 or between --output and sunrise.JPG. Neither is there any indication that --input and --output identify options.
Fortunately, the new System.CommandLine API provides a significant improvement on this simple scenario, and does so in a way I haven’t previously seen. The simplification is that you can program a Main entry point with a signature that matches the command line. In other words, the signature for Main becomes:
static void Main(string input, string output)
That’s right, System.CommandLine enables the automatic conversion of the --input and --output options into parameters on Main, replacing the need to even write a standard Main(string[] args) entry point. The msdnmagazine.com
only additional requirement is to reference an assembly that enables this scenario. You can find details on what to reference at itl.tc/syscmddf, as any instructions provided here are likely to be quickly dated once the assembly is released on NuGet. (No, there’s no language change to support this. Rather, when adding the reference, the project file is modified to include a build task that generates a standard Main meth- od with a body that uses reflection to call the “custom” entry point.)
Furthermore, arguments aren’t limited to strings. There’s a host of built-in converters (and support for custom converters) that allow you, for example, to use System.IO.FileInfo for the param- eter type on input and output, like so:
static void Main(FileInfo input, FileInfo output)
As described in the article section, “System.CommandLine Architecture,” System.CommandLine is broken into a core mod- ule and an app provider module. Configuring the command line from Main is an App Model implementation, but for now I’ll just refer to the entire API set as System.CommandLine.
The mapping between command-line arguments and Main method parameters is basic today, but still relatively capable for lots of programs. Let’s consider a slightly more complex imageconv command line that demonstrates some of the additional features. Figure 1 displays the command-line help.
The corresponding Main method that enables this updated command line is shown in Figure 2. Even though the example has nothing more than a fully documented Main method, there are numerous features enabled automatically. Let’s explore the functionality that’s built-in when you use System.CommandLine.
The first bit of functionality is the help output for the command line, which is inferred from the XML comments on Main. These comments not only allow for a general description of the program
Figure 1 Sample Command Line for imageconv
imageconv:
Converts an image file from one format to another.
Usage:
imageconv [options]
Options: --input
--output --x-crop-size
--y-crop-size --version
The path to the image file that is to be converted. The target name of the output after conversion.
The X dimension size to crop the picture.
The default is 0 indicating no cropping is required. The Y dimension size to crop the picture.
The default is 0 indicating no cropping is required. Display version information
Figure 2 Main Method Supporting the Updated imageconv Command Line
/// <summary>
/// Converts an image file from one format to another.
/// </summary>
/// <param name="input">The path to the image file that is to be
converted.</param>
/// <param name="output">The name of the output from the conversion.
</param>
/// <param name="xCropSize">The x dimension size to crop the picture.
The default is 0 indicating no cropping is required.</param>
/// <param name="yCropSize">The x dimension size to crop the picture. The default is 0 indicating no cropping is required.</param>
public static void Main(
FileInfo input, FileInfo output,
int xCropSize = 0, int yCropSize = 0)
March 2019 21


































































































   25   26   27   28   29