Skip to content

AddDelegateAsync or pass original arguments #766

Description

@WojciechNagorski

Is your feature request related to a problem? Please describe.
I would like to run ASP Core application in one of the command:

public static async Task Main(string[] args)
{
    var app = new CommandApp<RunCommand>();
    
    app.Configure(config =>
        {
            config.AddCommand<RunCommand>("db-migrate")
                .WithDescription("Only starts database migrations and exits the application.");
            config.AddCommand<RunCommand>("run")
                .WithDescription("Runs ASP core application");
        });
    await app.RunAsync(args);
}

But in this way, I'm not able to pass original args to my host:

public class RunCommand : AsyncCommand
{
    public override async Task<int> ExecuteAsync(CommandContext context)
    {
        var host = Host.CreateDefaultBuilder(args) // <-- here I need the program arguments, but context contains only parsed list
                .ConfigureWebHostDefaults(webBuilder =>
                    {
                        webBuilder.UseStartup<Startup>();
                    }).Build();

        await host.RunAsync();

        return 0;
    }
}

So I tried use the AddDelegate method instead of AddCommand, but this method can't be async.

public static async Task Main(string[] args)
{
    var app = new CommandApp<RunCommand>();

    app.Configure(config =>
        {
            config.AddCommand<RunCommand>("db-migrate")
                .WithDescription("Only starts database migrations and exits the application.");
            config.AddDelegate("run", context => RunApplication(args)) //<-- the RunApplication method can'd be async
                .WithDescription("Runs ASP core application");
        });

    await app.RunAsync(args);
}

public static async Task RunApplication(string[] args)
{
    var host = Host.CreateDefaultBuilder(args) // <-- here I need the program arguments, but context contains only parsed list
                .ConfigureWebHostDefaults(webBuilder =>
                    {
                        webBuilder.UseStartup<Startup>();
                    }).Build();

    await host.RunAsync();
}

Describe the solution you'd like
This problem can be solved in two ways:

  1. Add original parameters to the command context:
public class RunCommand : AsyncCommand
{
    public override async Task<int> ExecuteAsync(CommandContext context)
    {
        var args = context.OriginalArguments //<-- contains args from the main method

        return 0;
    }
}
  1. Support async deleget AddDelegateAsync:
public static async Task Main(string[] args)
{
    var app = new CommandApp<RunCommand>();

    app.Configure(config =>
        {
            config.AddDelegateAsync("run", async context => await RunApplication(args)) //<-- the new AddDelegateAsync method
        });

    await app.RunAsync(args);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions