Skip to content

Extensibility

Denis Zykov edited this page Oct 25, 2026 · 1 revision

Extensibility

CommandLine resolves the following services from the configured IServiceProvider and falls back to a built-in implementation when one is not registered:

Service Purpose
IConsole Output of help and errors, interruption token.
ITypeConversionProvider Conversion of option and value strings to parameter types.
IHelpTextProvider Text used in help and error messages.
ExceptionEventHandler Exception handlers, all registered handlers are called.

All of them, except handlers, could also be injected into verbs with [FromService].

Console

IConsole receives all output of CommandLine. Replace it to capture output in tests or to redirect it to a logger:

public class TestConsole : IConsole
{
  public readonly StringBuilder Output = new StringBuilder();

  public CancellationToken InterruptToken => CancellationToken.None;

  public void WriteLine(object? text = null) => this.Output.AppendLine(Convert.ToString(text));
  public void WriteErrorLine(object? text = null) => this.Output.AppendLine(Convert.ToString(text));
}
var console = new TestConsole();
var services = new ServiceContainer();
services.AddService(typeof(IConsole), console);

var exitCode = CommandLine
  .CreateFromArguments("hello", "--name", "Jake")
  .UseServiceProvider(() => services)
  .Use<Program>()
  .Run();

InterruptToken is linked into the verb's CancellationToken. The default console cancels it on Ctrl+C when CommandLineConfiguration.HookConsoleCancelKeyPress is true.

To write to the same console from a verb, inject it:

public static int Hello([FromService] IConsole console, string name)
{
  console.WriteLine("Hello " + name + "!");
  return 0;
}

Type conversion

Conversion is provided by the deniszykov.TypeConversion package, which is a dependency of CommandLine. Types listed in Supported .NET types work without configuration. To add your own conversion, register a TypeConversionProvider with it:

using deniszykov.TypeConversion;

var conversion = new TypeConversionProvider();
conversion.RegisterConversion<string, Money>(
  (value, format, formatProvider) => Money.Parse(value),
  ConversionQuality.Custom
);

var services = new ServiceContainer();
services.AddService(typeof(ITypeConversionProvider), conversion);

CommandLine
  .CreateFromArguments(arguments)
  .UseServiceProvider(() => services)
  .Use<Program>()
  .Run();
> myapp pay --money 12.5$

For a type you own, applying a TypeConverterAttribute or adding a static Parse(string) method is enough.

Help text

IHelpTextProvider supplies every text fragment used in help and error output (headers, "Usage:", "Options:", error messages, parameter type names). Implement it to translate or reword the output. See Help Text.

Clone this wiki locally