Using the library in a number of projects made me realize it was too hard to configure. That was mostly the result of it trying to do too much of the configuration automagically (e.g., scanning a list of provided assemblies to locate alternative interface implementationss and then picking the “best” one).
I decided the degree of magic had to be reduced significantly…but it wouldn’t matter because the programmer would know precisely which implementations he or she wanted to use anyway.
This also allowed me to stop using dependency injection to ensure things got configured correctly. Now you create an
IParser by doing this:
var optionsCollection = new OptionCollection( StringComparison.OrdinalIgnoreCase, new BindabilityValidator() ); var optionsGenerator = new OptionsGenerator( optionsCollection, StringComparison.OrdinalIgnoreCase ); var parsingTable = new ParsingTable( optionsGenerator ); var tokenizer = new Tokenizer( new WindowsLexicalElements() ); var parser = new Parser( optionsCollection, parsingTable, tokenizer );
And, if you’re willing to rely on the defaults it’s even easier:
var parser = Parser.GetWindowsDefault();
The parser can be added to the
IConfiguration system so that you can use its
var configRoot = new ConfigurationBuilder() .AddJ4JCommandLine( parser, out var options ) .Build(); // binds /x to ASwitch options.Bind<Target, bool>(x => x.ASwitch, "x"); // bind /t to ASingleValue (which is a string) options.Bind<Target, string>(x => x.ASingleValue, "t"); options.FinishConfiguration(); var target1 = configRoot.Get<Target>();
The FinishConfiguration() call is very important. If you don’t include it the parsing will fail.
For more information on the library, how to use it, etc., please consult: