@@ -167,6 +167,36 @@ public ArgumentInfo(char shortName, string longName, string helpText, PropertyIn
167
167
public char ShortName { get ; }
168
168
}
169
169
170
+ /// <summary>
171
+ /// Parsing options.
172
+ /// </summary>
173
+ public class ArgumentParseOptions
174
+ {
175
+ /// <summary>
176
+ /// Gets or sets the <see cref="Type"/> for which the command line string is to be parsed.
177
+ /// </summary>
178
+ /// <remarks>
179
+ /// Supersedes combination options; arguments backed by properties of a collection type are combined, while those that aren't are not.
180
+ /// </remarks>
181
+ public Type TargetType { get ; set ; }
182
+
183
+ /// <summary>
184
+ /// Gets or sets a value indicating whether duplicate argument values should be combined into a list.
185
+ /// </summary>
186
+ /// <remarks>
187
+ /// Only applicable if <see cref="TargetType"/> is not specified.
188
+ /// </remarks>
189
+ public bool CombineAllMultiples { get ; set ; }
190
+
191
+ /// <summary>
192
+ /// Gets or sets a value indicating whether duplicate argument values for arguments in the array should be combined into a list.
193
+ /// </summary>
194
+ /// <remarks>
195
+ /// Only applicable if <see cref="TargetType"/> is not specified.
196
+ /// </remarks>
197
+ public string [ ] CombinableArguments { get ; set ; } = Array . Empty < string > ( ) ;
198
+ }
199
+
170
200
/// <summary>
171
201
/// Provides static methods used to retrieve the command line arguments and operands with which the application was
172
202
/// started, as well as a Type to contain them.
@@ -310,19 +340,53 @@ public object this[string key]
310
340
return retVal ;
311
341
}
312
342
343
+ /// <summary>
344
+ /// Returns a dictionary containing the values specified in the command line arguments with which the application was
345
+ /// started, keyed by argument name.
346
+ /// </summary>
347
+ /// <param name="configure">An action to configure the provided <see cref="ArgumentParseOptions"/> instance.</param>
348
+ /// <returns>
349
+ /// The dictionary containing the arguments and values specified in the command line arguments with which the
350
+ /// application was started.
351
+ /// </returns>
352
+ public static Arguments Parse ( Action < ArgumentParseOptions > configure = null )
353
+ {
354
+ return Parse ( null , configure ) ;
355
+ }
356
+
313
357
/// <summary>
314
358
/// Returns a dictionary containing the values specified in the command line arguments with which the application was
315
359
/// started, keyed by argument name.
316
360
/// </summary>
317
361
/// <param name="commandLineString">The command line arguments with which the application was started.</param>
318
- /// <param name="type">The <see cref="Type"/> for which the command line string is to be parsed.</param>
319
- /// <param name="caller">Internal parameter used to identify the calling method.</param>
362
+ /// <param name="configure">An action to configure the provided <see cref="ArgumentParseOptions"/> instance.</param>
363
+ /// <returns>
364
+ /// The dictionary containing the arguments and values specified in the command line arguments with which the
365
+ /// application was started.
366
+ /// </returns>
367
+ public static Arguments Parse ( string commandLineString , Action < ArgumentParseOptions > configure = null )
368
+ {
369
+ configure = configure ?? new Action < ArgumentParseOptions > ( ( _ ) => { } ) ;
370
+ var options = new ArgumentParseOptions ( ) ;
371
+ configure ( options ) ;
372
+
373
+ return Parse ( commandLineString , options ) ;
374
+ }
375
+
376
+ /// <summary>
377
+ /// Returns a dictionary containing the values specified in the command line arguments with which the application was
378
+ /// started, keyed by argument name.
379
+ /// </summary>
380
+ /// <param name="commandLineString">The command line arguments with which the application was started.</param>
381
+ /// <param name="options">Parser options.</param>
320
382
/// <returns>
321
383
/// The dictionary containing the arguments and values specified in the command line arguments with which the
322
384
/// application was started.
323
385
/// </returns>
324
- public static Arguments Parse ( string commandLineString = default ( string ) , Type type = null , [ CallerMemberName ] string caller = default ( string ) )
386
+ public static Arguments Parse ( string commandLineString , ArgumentParseOptions options )
325
387
{
388
+ options = options ?? new ArgumentParseOptions ( ) ;
389
+
326
390
commandLineString = commandLineString == default ( string ) || string . IsNullOrEmpty ( commandLineString ) ? Environment . CommandLine : commandLineString ;
327
391
328
392
List < KeyValuePair < string , string > > argumentList ;
@@ -353,8 +417,8 @@ public object this[string key]
353
417
operandList = GetOperandList ( commandLineString ) ;
354
418
}
355
419
356
- var argumentDictionary = GetArgumentDictionary ( argumentList , type ) ;
357
- return new Arguments ( commandLineString , argumentList , argumentDictionary , operandList , type ) ;
420
+ var argumentDictionary = GetArgumentDictionary ( argumentList , options ) ;
421
+ return new Arguments ( commandLineString , argumentList , argumentDictionary , operandList , options . TargetType ) ;
358
422
}
359
423
360
424
/// <summary>
@@ -368,7 +432,7 @@ public object this[string key]
368
432
public static void Populate ( string commandLineString = default ( string ) , bool clearExistingValues = true , [ CallerMemberName ] string caller = default ( string ) )
369
433
{
370
434
var type = ArgumentsExtensions . GetCallingType ( caller ) ;
371
- Populate ( type , Parse ( commandLineString , type ) , clearExistingValues ) ;
435
+ Populate ( type , Parse ( commandLineString , options => options . TargetType = type ) , clearExistingValues ) ;
372
436
}
373
437
374
438
/// <summary>
@@ -383,7 +447,7 @@ public object this[string key]
383
447
/// <param name="clearExistingValues">Whether to clear the properties before populating them. Defaults to true.</param>
384
448
public static void Populate ( Type type , string commandLineString = default ( string ) , bool clearExistingValues = true )
385
449
{
386
- Populate ( type , Parse ( commandLineString , type ) , clearExistingValues ) ;
450
+ Populate ( type , Parse ( commandLineString , options => options . TargetType = type ) , clearExistingValues ) ;
387
451
}
388
452
389
453
/// <summary>
@@ -537,10 +601,10 @@ private static void ClearProperties(Dictionary<string, PropertyInfo> properties)
537
601
}
538
602
}
539
603
540
- private static Dictionary < string , object > GetArgumentDictionary ( List < KeyValuePair < string , string > > argumentList , Type targetType = null )
604
+ private static Dictionary < string , object > GetArgumentDictionary ( List < KeyValuePair < string , string > > argumentList , ArgumentParseOptions options )
541
605
{
542
606
var dict = new ConcurrentDictionary < string , object > ( ) ;
543
- var argumentInfo = targetType == null ? new List < ArgumentInfo > ( ) : GetArgumentInfo ( targetType ) ;
607
+ var argumentInfo = options . TargetType == null ? new List < ArgumentInfo > ( ) : GetArgumentInfo ( options . TargetType ) ;
544
608
545
609
foreach ( var arg in argumentList )
546
610
{
@@ -567,7 +631,22 @@ private static Dictionary<string, object> GetArgumentDictionary(List<KeyValuePai
567
631
}
568
632
else
569
633
{
570
- dict . AddOrUpdate ( arg . Key , arg . Value , ( key , existingValue ) => arg . Value ) ;
634
+ if ( dict . ContainsKey ( arg . Key ) && ( options . CombineAllMultiples || options . CombinableArguments . Contains ( arg . Key ) ) )
635
+ {
636
+ dict . AddOrUpdate ( arg . Key , arg . Value , ( key , existingValue ) =>
637
+ {
638
+ if ( existingValue . GetType ( ) == typeof ( List < object > ) )
639
+ {
640
+ return ( ( List < object > ) existingValue ) . Concat ( new [ ] { arg . Value } ) . ToList ( ) ;
641
+ }
642
+
643
+ return new List < object > ( ) { existingValue , arg . Value } ;
644
+ } ) ;
645
+ }
646
+ else
647
+ {
648
+ dict . AddOrUpdate ( arg . Key , arg . Value , ( key , existingValue ) => arg . Value ) ;
649
+ }
571
650
}
572
651
}
573
652
0 commit comments