command-line-api
command-line-api copied to clipboard
Refactor Hosting extensions
- [x] Remove
InvocationLifetimeOriginally,System.CommandLine.Hostingwas designed to depend only onMicrosoft.Extensions.Hosting.Abstractionswhich made theInvocationLifetimeclass necessary. Currently however, the library depends on the fullMicrosoft.Extensions.Hostinglibrary, soInvocationLifetimeis no longer required as the functionality of theConsoleLifetimeclass fully (and more extensively) covers its functionality. We should however provide guidance that you want set the process termination timeout of theCliConfigurationtonullwhen usingSystem.CommandLine.Hosting(theUseHostextension method does that as part of its implementation). - [ ] Introduce
HostedServiceAction, aCliActionthat using a .NET Generic Host hosted service as the execution for a CLI action.- Originally, one of the issues with using a Hosted Service as the Action for a CLI Command was that the .NET Generic Host does not automatically shutdown when the hosted service completes its execution task (that is by design, as Hosted services generally run in the background for the entire liftetime of the application).
HostedServiceActionwill automatically shut down the .NET Generic Host when the Hosted Service completes its work, i.e. the command finishes. - Add
CliHostedService, a simple derivison fromBackgroundService, which provides aCliAsyncAction-similar abstractInvokeAsyncmethod to override which also allows returning back an integer result value.HostedServiceActionwill use the return value fromCliHostedServiceto return the result integer for the invocation. This class also avoids confusion regarding the nameBackgroundServiceas the main handler for a CLI Command.
- Originally, one of the issues with using a Hosted Service as the Action for a CLI Command was that the .NET Generic Host does not automatically shutdown when the hosted service completes its execution task (that is by design, as Hosted services generally run in the background for the entire liftetime of the application).
- [ ] Rename
HostingActiontoHostingWrapperAction- Create a new base class
HostingActionand make bothHostingWrapperActionandHostedServiceActionderive from it. - Move the logic of creating the Host and starting it part of the base class, the
HostingWrapperActionsimply wraps the underlying action, whileHostedServiceActionsimply deals with waiting for the hosted service to complete.
- Create a new base class
- [ ] Prepare extension points for using the modern generic host builder introduced in .NET 8.
.NET 8 introduces the
HostApplicationBuilderclass as an alternative to theHostBuilderandIHostBuilderinterfaces. Annoyingly, theHostApplicationBuilderdoes not implement theIHostBuilderinterface necessary for the original implementation of theSystem.CommandLine.Hostingextensions.- Add an internal very limited wrapper around
HostApplicationBuilderthat (partially) implementsIHostBuilder. - Add a generic type argument to the
HostingActionbase class that supports multiple different Host builders. - Adding this functionality will require a new TFM for the
System.CommandLine.Hostinglibrary. Current proposed implementation uses#ifdefset up for multi-targeting.
- Add an internal very limited wrapper around
- [ ] Add a publically settable
ConfigureHostproperty on theHostingActionbase class.- Since the new
HostedServiceActionis publically exposed and constructable is is useful to be able to allow for per-command separate ConfigureHost methods. UseHostwill now combine itsconfigureHostargument with already existingConfigureHostdelegates that have previously been set onHostingActionsset for Cli commands in the CLI configuration.
- Since the new
- [ ] Add a new
UseHostextension method forAsynchronousCliActioninstances that allows for per-command specific Host configuration actions - [ ] Provide more examples for a complex multi-command set-up in
HostedPlayground- Show how multiple
HostedServiceActionscan have their individual command-specificConfigureHostdelegates with a shared whole appConfigureHostdelegate. - Show differences between using just a regular
CommandHandlerwith a method with hosting vs. using aCliHostedService.
- Show how multiple
- Add tests for new introduced features in this PR
- [ ] Tests for combining
ConfigureHostfromUseHostandHostingAction - [ ] Tests for using
HostApplicationBuilder - [ ] Tests for
HostedServiceAction
- [ ] Tests for combining
https://github.com/dotnet/command-line-api/issues/2390 shows that there might be a use-case for an UseHost extension method on BindingHandler that would allow to create per-command Host configurations instead of the current UseHost extension that is applied for the entire configuration.