/// <summary>Creates a new instance.</summary> /// <param name="logger">A logger</param> /// <param name="state">The command line state</param> /// <param name="serviceProvider">The DI service provider</param> public CommandLineService(ILogger <CommandLineService <T> > logger, CommandLineState state, IServiceProvider serviceProvider) { _logger = logger; _state = state; logger.LogDebug("Constructing CommandLineApplication<{type}> with args [{args}]", typeof(T).FullName, string.Join(",", state.Arguments)); _application = new CommandLineApplication <T>(state.Console, state.WorkingDirectory, true); _application.Conventions .UseAttributes() //.SetAppNameFromEntryAssembly() //.SetRemainingArgsPropertyOnModel() .SetSubcommandPropertyOnModel() .SetParentPropertyOnModel() .UseOnExecuteMethodFromModel() //.UseOnValidateMethodFromModel() //.UseOnValidationErrorMethodFromModel() .UseDefaultHelpOption() .UseCommandNameFromModelType() .UseConstructorInjection(serviceProvider); foreach (IConvention convention in serviceProvider.GetServices <IConvention>()) { _application.Conventions.AddConvention(convention); } }
/// <summary> /// Runs an instance of <typeparamref name="TApp" /> using <see cref="CommandLineApplication" /> to provide command line parsing on the given /// <paramref name="args" />. This method should be the primary approach taken for command line applications. /// </summary> /// <typeparam name="TApp">The type of the command line application implementation</typeparam> /// <param name="hostBuilder">This instance</param> /// <param name="args">The command line arguments</param> /// <param name="cancellationToken">A cancellation token</param> /// <returns>A task whose result is the exit code of the application</returns> public static async Task <int> RunCommandLineApplicationAsync <TApp>( this IHostBuilder hostBuilder, string[] args, CancellationToken cancellationToken = default) where TApp : class { StoreExceptionHandler exceptionHandler = new StoreExceptionHandler(); CommandLineState state = new CommandLineState(args); hostBuilder.ConfigureServices( (context, services) => { services .TryAddSingleton <IUnhandledExceptionHandler>(exceptionHandler); services .AddSingleton <IHostLifetime, CommandLineLifetime>() .TryAddSingleton(PhysicalConsole.Singleton); services .AddSingleton(provider => { state.SetConsole(provider.GetService <IConsole>()); return(state); }) .AddSingleton <CommandLineContext>(state) .AddSingleton <ICommandLineService, CommandLineService <TApp> >(); }); using IHost host = hostBuilder.Build(); await host.RunAsync(cancellationToken).ConfigureAwait(false); if (exceptionHandler.StoredException != null) { ExceptionDispatchInfo.Capture(exceptionHandler.StoredException).Throw(); } return(state.ExitCode); }