Closed thegreatco closed 4 years ago
Can you also give an example use case where generic host could be helpful?
Closing as I don't see much value in this. The only benefit of the generic host is the DI, which is trivial to add as it is. Other features like logging, configuration, etc are not really relevant to CliFx.
I think I'd like to second this idea. Although it's feasible to set DI up, I guess the question people will always have is whether the example from @thegreatco is the best approach.
I wouldn't worry so much about logging, configuration and others being the goal here, so much as just having a nice official way to add support for command line arguments to worker projects.
There is an easier way to set up DI without IHost
, it's covered in the readme. But if you want to use IHost
then something like the example above will work. Although I'm not entirely sure what's the benefit.
Well, the benefit is that your library makes it really nice to parse command line arguments, and people authoring worker projects would like to use that.
It's less about what clifx would get in this scenario, so much as just having an official way/some guidance to use this library in worker projects.
Unfortunately I haven't done that myself, so can't advise on what's the best solution.
I would like to use BackgroundService to integrate CliFx and I think this approach is flexible. Here is an example and I'm writing a library Modulight.Modules.CommandLine based on CliFx in this way to support hosting.
public class DefaultCommand : ICommand
{
public async ValueTask ExecuteAsync(IConsole console)
{
await console.Output.WriteLineAsync("Hello world!");
}
}
static class Program
{
public static async Task Main(string[] args) => await CreateHostBuilder(args).Build().RunAsync();
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddSingleton<DefaultCommand>();
services.AddHostedService<Worker>();
})
.UseConsoleLifetime();
}
class Worker : BackgroundService
{
public Worker(IServiceProvider services, IHostApplicationLifetime lifetime)
{
Services = services;
Lifetime = lifetime;
}
IServiceProvider Services { get; }
IHostApplicationLifetime Lifetime { get; }
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var exitCode = await new CliApplicationBuilder()
.AddCommandsFromThisAssembly()
.UseTypeActivator(Services.GetService)
.Build()
.RunAsync();
Environment.ExitCode = exitCode;
Lifetime.StopApplication();
}
}
Add support for configuring and launching the application under the .NET Generic Host.
Currently, this can be achieved in a sort of hacky way:
I envision this as something like
Then running it by either calling the existing
Build().RunAsync()
or.RunConsoleAsync() on
IHostBuilderor adding a new
.RunAsCliApplicationAsync()on either
IHostBuilderor
IHost` (or similar).