JasperFx / oakton

Parsing and Utilities for Command Line Tools in .Net
http://jasperfx.github.io/oakton
Apache License 2.0
308 stars 41 forks source link

Fix custom optional usages #32

Closed aidanjryan closed 5 years ago

aidanjryan commented 5 years ago

Fixes #31

aidanjryan commented 5 years ago

@kae @jeremydmiller This is an un-fun catch-22. The "BeforeBuild" approach wants to create usages to allow instantiating input before the command is created, in order for client code to configure DI based on that input prior to command creation. Commands need their constructors to run in order to call the base Usage method and add custom usages which are required for initializing the input.

The fix here tries to explicitly use the ActivatorCommandCreator to create the command using its default constructor, then use that constructed command's usages to get an input instance and pass it to BeforeBuild.

This means that anyone who wants to opt-in to BeforeBuild needs to supply a default constructor, even if they are using DI for the actual command.

I feel like an ultimately clean solution would be to decouple custom usage declaration from the command constructor. Perhaps a command would be generic of <Input, IUsages> when it needs custom usages, given a Usages interface like

interface IUsages<TCommand>
{
  UsageGraph CustomUsages { get; }  
}