-
Notifications
You must be signed in to change notification settings - Fork 293
Plug in Friendly Architecture
IMPORTANT NOTE: This wiki refers to latest stables, if a beta version is available in github master branch please refer to Latest Version.
The parser can be configured to ignore valid input and defer its processing to another part of the application you’re designing. This fits particularly well in a plug-in scenario.
Now suppose that your application define an option to allow loading of a particular plug-in:
class AppOptions {
[Option('p', "plugin", Required = true, HelpText = "Plug-In to activate.")]
public string PlugInName { get; set; }
// Remainder omitted
}
Ever for the sake of the sample, suppose your application is able to load a plugin defined in Options::PlugInName
. Hence for brevity will say also that such plug-in lives in its own DLL in a particular folder and requires its particular set of command line options.
So when a user write the following line at the command prompt:
$ coolapp --plugin dropTempTables TMP_A TMP_B --nobackup
the parser has no knowledge of what came after the plug-in name (dropTempTables
in this case).
The only thing it could be able to do is only to ensure whatever the input is lexically correct or not.
This behaviour is disabled by default and it also not available in the pre-built singleton. To enable it you must create the parser instance by your own.
One way is to properly configure a ParserSettings
:
var parser = new CommandLine.Parser(with => with.IgnoreUnknownArguments = true);
Now you can safely invoke ParseArguments
as always:
var appOptions = new AppOptions();
if (parser.ParseArguments(args, appOptions)) {
// parsing succeds
}
The plug-in of the previous example with an options class defined as follows:
class DropTempTablesOptions {
[Option("no-backup", HelpText = "Turn-off backup log.")]
public bool NoBackup { get; set; }
[ValueList(typeof(List<string>))]
public IList<string> TempTablesToDrop { get; set; }
}
can re-use the same parser instance or, depending on your design, creates a new one as long as IgnoreUnknownArguments
is set to true.
It follows a simplistic flow just to understand better this feature:
var appOptions = new AppOptions();
if (parser.ParseArguments(args, appOptions)) {
// Parsing succeds; plug-in arguments ignored,
// we can load user plugin and proceed
if (appOptions.PlugInName.ToUpperInvariant() == "DROPTEMPTABLES") {
// Loading specified plug-in
var plugIn = PlugInManager.Load(appOptions.PlugInName);
var dropTempTablesOptions = new DropTempTablesOptions();
if (parser.ParseArguments(args, dropTempTablesOptions)) {
// Parsing succeds; application arguments ignored,
// we can perform plug-in related operations
plugIn.ConfigureWith(dropTempTablesOptions);
Console.WriteLine("Dropping DB tables ...");
plugIn.DoJob();
}
// else if ...
}
}
This useful feature from one of ours main contributor is still not implemented in pre-release 2.0 (that's a deep refactoring inside/out), but it will.