-
Notifications
You must be signed in to change notification settings - Fork 386
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add generic host builder pattern for System.CommandLine.Hosting #918
Comments
Would be nice to make it easier to use the Worker Service, as well. Referencing #556. |
@shaggygi I think this solution allows it, because ParseResult is added as Singleton, so you can consume it from Worker. Currently, it is not documented though. |
You all will teach me a good bit on this, so let me start with what might be a simple question. When generic host is in place, does it make sense to have the CommandLine Host on the stack, or (at least as an option) can we put the results in an instance (from StarFruit) available via DI ad then step out of the way. (Question is based on current assumptions about how GenericHost works) |
@KathleenDollard services.AddOptions<MyAppOptions>()
.BindCommandLine();
// source: src\System.CommandLine.Hosting\HostingExtensions.cs:70 Although, it introduces a cyclic dependency between
The current implementation gets around this by making |
Can the patterns we use here be generalized to include |
Unfortunatelly, public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureCommandLineBuilder(cmdBuilder => // CommandLineBuilder
{
cmdBuilder.UseReflectionAppModel(); // e.g. https://github.com/KathleenDollard/command-line-api-starfruit
});
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
}); |
To the extent that the patterns are similar, it would be good to have approaches and matching code for both, even if it means we need another project. |
Aarrgh. Seems like an understanding of why IWebHostBuilder and IHostBuilder differ would be a starting point. I don't yet see why multiple projects help over other approaches. |
They'll have different dependencies and you won't want the union of the two dependency graphs. |
I think a more inverted model, and doing away with the concept of a // Generic host:
new HostBuilder()
.ConfigureCommandLine((CommandLineBuilder cmdLineBuilder) =>
{
cmdBuilder.DoStuff();
})
// Web host:
new WebHostBuilder()
.ConfigureCommandLine((CommandLineBuilder cmdLineBuilder) =>
{
cmdBuilder.DoStuff();
}) |
For configuration purposes next methods are used: new HostBuilder()
.ConfigureHostConfiguration(config => config .AddCommandLine(args))
.ConfigureAppConfiguration((hostingContext, config) => config.AddCommandLine(args));
// Microsoft.Extensions.Hosting.IHostBuilder ConfigureHostConfiguration
// Microsoft.Extensions.Hosting.IHostBuilder ConfigureAppConfiguration Please see: comment above
services.AddHostedService<CommandLineExecutorService>()
I apologize for so many questions. It is quite an interesting bit of functionality to me. |
re: 1. I think the use cases are the same for both generic host and web host, which is I want to use DI, logging, etc. in an app that also has a command line experience that provides help, completions, and so on. The application type is orthogonal to the desire to have a good CLI. As examples, |
Update after some exploration. You can find the code I wrote on this at https://github.com/KathleenDollard/command-line-api-starfruit. It's the hosting projects in the main branch. Here are my updated thoughts:
Sorry for the long post. |
I've been struggling a bit with working on a way in a sample asp.net project to use the CommandLineBuilder / hosting project to dynamically create hosted services using IHost/IHostBuilder based on the parse result. I'd see myself registering sub commands in |
@niemyjski I think this under consideration, please see #1025 (comment) |
I have a different desired usage: I want to use the hosted services injected in the host to define which commands are available. In the bigger context, this is for a .NET Core worker app that normally runs as a Win32 service and performs scheduled jobs, and the command line interface is for manually executing one of those jobs. Currently, I'm doing this by creating the host with the full command line (it ignores unknown arguments), and then I create a command line with dynamically added commands which directly invoke the appropriate hosted service. In order to allow dotnet host/app arguments (.NET command line configuration provider), I also have a catch-all The drawback to my current approach is that the error handling isn't great. The host attempts to parse any System.CommandLine arguments into configuration values, and the System.CommandLine ignores any unknown arguments to allow for host configuration. So typos are not obvious. I tried creating a separate Anyway, it seems like there are two different and possibly conflicting desires in this thread:
Good luck! ;) |
Align
System.CommadLine.Hosting
model with the way ASP.NET Core uses Generic Host.It should be possible to configure CommandLineBuilder like this:
The text was updated successfully, but these errors were encountered: