MinimalCommandLine 0.0.3-alpha
See the version list below for details.
dotnet add package MinimalCommandLine --version 0.0.3-alpha
NuGet\Install-Package MinimalCommandLine -Version 0.0.3-alpha
<PackageReference Include="MinimalCommandLine" Version="0.0.3-alpha" />
<PackageVersion Include="MinimalCommandLine" Version="0.0.3-alpha" />
<PackageReference Include="MinimalCommandLine" />
paket add MinimalCommandLine --version 0.0.3-alpha
#r "nuget: MinimalCommandLine, 0.0.3-alpha"
#:package MinimalCommandLine@0.0.3-alpha
#addin nuget:?package=MinimalCommandLine&version=0.0.3-alpha&prerelease
#tool nuget:?package=MinimalCommandLine&version=0.0.3-alpha&prerelease
System.CommandLine.Minimal
A set of minimal builders that sits on top of the
System.CommandLinenamespace to give an experience similar to the ASP.Net Core minimal API builders.Primary Goal:
The primary goal of this library design is to give the developer the option to use one of the following approaches:
- Inline Approach: To put the logic directly with the API design, which allows for maximum readability.
- Separate Approach (static class): Separate the API design from the actual logic using a static handler, which allows for high testability.
- Separate Approach (instance class): Separate the API from the logic using an instance class, which allows for dependency injection and high testability.
Hello World:
using System.CommandLine.Minimal;
var app = new MinimalCommandLineBuilder()
    .Build();
app.AddRootDescription("A simple demo app for the command line.")
    .AddRootArgument<string>("Message")
    .AddRootOption<string>("--first-option", opt => opt.AddAlias("-o1"))
    .AddRootOption<string>("--second-option")
    .SetRootHandler(
        (string message, string option1, string option2) =>
        {
            Console.WriteLine($"Hello World!  {message}");
            Console.WriteLine($"  Option 1:{option1}, Option2 {option2}");
        }
    );
app.Execute(args);
Getting Started
git clone https://github.com/dotnetKyle/MinimalCommandLine.git
Using Visual Studio:
Set DemoApp as the startup project.
Check the Properties/launchSettings.json file, ensure that the commandLineArgs property is set to -h
Using the dotnet CLI:
dotnet build DemoApp.csproj -c Debug
cd \bin\Debug\net6.0\
DemoApp.exe -h
Simple Examples:
Inline Approach:
The API and the application logic are together.  Uses an Action<Task> directly in the Program.cs.
var app = new MinimalCommandLineBuilder()
  .Build();
app.AddRootDescription("Create X509Certificates.");
// generate a root CA certificate
app.AddCommand("rootCA"
  cmdOptions => 
  {
    cmdOptions
      .AddCommandDescription("Create a self-signed root certificate authority.")
      .AddArgument<string>("CommonName", argument =>
        argument.AddHelpName("Common Name")
          .AddDescription("Add a common name to the certificate's subject name.")
      )
        .AddOption<string[]>("-ou", option =>
          option.AddAlias("--organizational-unit")
            .AddDescription(
              "Add one or more Organizational Units (OUs) to the certificate's subject name."
            )
          )
        .AddOption<DateOnly>("-na", option =>
          option.AddAlias("--not-after")
            .AddDescription("Add a date that the certificate cannot be used after.")
            .AddDefaultValue(DateOnly.FromDateTime(DateTime.UtcNow.AddYears(10)))
          )
        // Bind the application logic here
        .SetHandler(async (string commonName, string[] OUs, DateOnly notAfter) =>
        {
          var notAfterDate = notAfter.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc);
          if (OUs is null)
            OUs = Array.Empty<string>();
          var filePath = Path.Combine(Environment.CurrentDirectory, "rootCA.pfx");
          var subjectName = $"CN={commonName}";
          foreach (var ou in OUs)
            subjectName += $", OU={ou}";
          subjectName += $", O=Your Org Name Here, C=USA";
          using (var rsa = RSA.Create(2048))
          {
            var req = new CertificateRequest(
              subjectName,
              rsa,
              HashAlgorithmName.SHA256,
              RSASignaturePadding.Pkcs1);
            req.CertificateExtensions.Add(
              new X509BasicConstraintsExtension(true, false, 0, true)
            );
            using (var cert = req.CreateSelfSigned(DateTime.UtcNow,notAfterDate))
            {
              var pfx = cert.Export(X509ContentType.Pfx);
              await File.WriteAllBytesAsync(filePath, pfx);
              Console.WriteLine(filePath);
            }
          }
        })
  });
Separate Approach (static class):
Same logic as above but inside a static method allows for the parameters to have optional values (which are automatically to the API help convention).
var app = new MinimalCommandLineBuilder()
  .Build();
app.AddRootDescription("Create X509Certificates.");
// generate a rootCA certificate
app.AddCommand("rootCA"
  cmdOptions => 
  {
    cmdOptions
      .AddCommandDescription("Create a self-signed root certificate authority.")
      .AddArgument<string>("CommonName", argument =>
        argument.AddHelpName("Common Name")
          .AddDescription("Add a common name to the certificate's subject name.")
      )
        .AddOption<string[]>("-ou", option =>
          option.AddAlias("--organizational-unit")
            .AddDescription("Add one or more OUs to the certificate's subject name.")
          )
        .AddOption<string>("-o", option =>
          option.AddAlias("--organization")
            .AddDescription("Override the default organization name.")
          )
        // Use a static method for the application logic
        .SetHandler(RootCaGenerator.GenerateSelfSigned);
    });
public static class RootCaGenerator
{
  public static async Task GenerateSelfSigned(
      string commonName, 
      string[] OUs, 
      string organization = "Your Org Here")
  {
    // Truncated for brevity
  }
}
Separate Approach (instance class with dependency injection):
Uses a class instance and gets dependencies from DI.
// add the command and it's dependencies to DI
var app = new MinimalCommandLineBuilder()
  .AddTransient<ISerialNumberProvider, FileSystemSerialNumberProvider>()
  .AddTransient<IntermediateCaGenerator>()
  .Build();
app.AddRootDescription("Create X509Certificates.");
// generate a intermediateCA certificate
app.MapCommand<IntermediateCaGenerator>("intermediateCA", 
  // this parameter is a binder to map the command to the instance method containing the application logic
  handler => handler.GenerateCaAsync,
  cmdOptions => 
  {
    cmdOptions
      .AddCommandDescription("Create a intermediate certificate authority.")
      .AddArgument<string>("CommonName", argument =>
        argument.AddHelpName("Common Name")
          .AddDescription("Add a common name to the certificate's subject name.")
      )
      .AddArgument<string>("IssuerCertificate", argument =>
        argument.AddHelpName("Issuer Certificate")
          .AddDescription("Add an issuer certificate with its private key.")
      )
      .AddOption<string[]>("-ou", option =>
        // truncated for brevity
    });
public class IntermediateCaGenerator
{
  ISerialNumberProvider _serialNumberProvider;
  public IntermediateCaGenerator(ISerialNumberProvider serialNumberProvider)
  {
    _serialNumberProvider = serialNumberProvider;
  }
  public async Task GenerateCaAsync(string commonName, string issuerFilePath)
  {
    var certificateSerialNumber = _serialNumberProvider.NextSerialNumber();
    // Truncated for brevity
  }
}
public class FileSystemSerialNumberProvider : IFileSystemSerialNumberProvider
{
  // Truncated for brevity
}
| Product | Versions Compatible and additional computed target framework versions. | 
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. | 
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. | 
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. | 
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. | 
| MonoAndroid | monoandroid was computed. | 
| MonoMac | monomac was computed. | 
| MonoTouch | monotouch was computed. | 
| Tizen | tizen40 was computed. tizen60 was computed. | 
| Xamarin.iOS | xamarinios was computed. | 
| Xamarin.Mac | xamarinmac was computed. | 
| Xamarin.TVOS | xamarintvos was computed. | 
| Xamarin.WatchOS | xamarinwatchos was computed. | 
- 
                                                    .NETStandard 2.0- Microsoft.Extensions.Hosting (>= 6.0.1)
- System.CommandLine (>= 2.0.0-beta4.22272.1)
 
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | 
|---|---|---|
| 0.5.0.31-alpha | 32 | 10/28/2025 | 
| 0.5.0.30-alpha | 43 | 10/25/2025 | 
| 0.5.0.29-alpha | 40 | 10/25/2025 | 
| 0.5.0.28-alpha | 108 | 10/23/2025 | 
| 0.5.0.27-alpha | 113 | 10/22/2025 | 
| 0.5.0.25-alpha | 120 | 10/19/2025 | 
| 0.5.0.22-alpha | 115 | 10/14/2025 | 
| 0.5.0.21-alpha | 119 | 10/14/2025 | 
| 0.5.0.20-alpha | 119 | 10/13/2025 | 
| 0.5.0.19-alpha | 118 | 10/13/2025 | 
| 0.5.0.18-alpha | 102 | 10/12/2025 | 
| 0.5.0.17-alpha | 94 | 10/12/2025 | 
| 0.5.0.16-alpha | 99 | 10/12/2025 | 
| 0.5.0.15-alpha | 102 | 10/12/2025 | 
| 0.5.0.14-alpha | 99 | 10/12/2025 | 
| 0.5.0.13-alpha | 56 | 10/11/2025 | 
| 0.5.0.12-alpha | 57 | 10/11/2025 | 
| 0.5.0.11-alpha | 103 | 9/6/2025 | 
| 0.5.0.10 | 172 | 8/29/2025 | 
| 0.5.0.10-alpha | 171 | 8/26/2025 | 
| 0.5.0.9 | 157 | 7/1/2025 | 
| 0.5.0.9-alpha | 129 | 7/1/2025 | 
| 0.5.0.8 | 107 | 6/29/2025 | 
| 0.5.0.8-alpha | 81 | 6/29/2025 | 
| 0.5.0.7 | 106 | 6/28/2025 | 
| 0.5.0.7-alpha | 82 | 6/28/2025 | 
| 0.0.3 | 1,006 | 9/14/2022 | 
| 0.0.3-alpha | 260 | 9/14/2022 | 
| 0.0.2 | 279 | 9/14/2022 | 
| 0.0.2-alpha | 261 | 9/14/2022 | 
Added missing support for the Root Command.