dotnet / dotnet/command-line-api

[API Proposal]: Add ``WithHandler`` to CommandExtensions.

Open
#1,364 5 comments 3 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
3.7k
Forks
428
PR merge metrics
No merged PRs in 30d

Description

I personally manually make my own extension method for ``Command`` in System.CommandLine to register an event handler using Reflection.

However I think it should be possible to instead bring it on over to System.CommandLine.

```cs
public static Command WithHandler(this Command command, string symbolName)
{
return command.WithHandler(
typeof(T).GetMethod(
symbolName,
BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly));
}
public static Command WithHandler(this Command command, MethodInfo? methodInfo)
{
if (methodInfo is null)
{
return command;
}

command.Handler = CommandHandler.Create(methodInfo!);
return command;
}
```

However I think the reflection one could be skipped if it's not wanted and take in the one that takes in ``MethodInfo``.

With this one can then define their handlers like so:

```cs
var cmd = new RootCommand
{
new Option(new[] { "--help", "help" }, "Shows the help message for the program."),
new Option("--version", "Shows the version of this command-line program."),
new Command("build", "builds a changelog or news file from any *.master file in the current or sub directory.")
{
}.WithHandler(nameof(Commands.BuildCommandHandler)),
new Command("new", string.Empty)
{
new Command("release", "Creates a new pending release folder and imports it in the *.master file in the current or sub directory.")
{
new Argument("release", "The new release version."),
}.WithHandler(nameof(Commands.NewReleaseCommandHandler)),
new Command("entry", "Creates a new entry file for the current pending release.")
{
new Argument("content", "The content to add to the new entry."),
}.WithHandler(nameof(Commands.NewEntryCommandHandler)),
},
new Command("finalize", string.Empty)
{
new Command("release", "Finalizes a pending release to a section file.")
{
}.WithHandler(nameof(Commands.FinalizeReleaseCommandHandler)),
},
}.WithHandler(nameof(Commands.GlobalCommandHandler));
return await cmd.InvokeAsync(args);
```

Which is much better than using multiple variables, assigning specific ones an handler, and then call ``InvokeAsync``. Also it's much more readable this way too.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.