private void AddArgument(PropertyInfo prop, ArgumentAttribute argumentAttr, ConventionContext convention, SortedList <int, CommandArgument> argOrder, Dictionary <int, PropertyInfo> argPropOrder) { var argument = argumentAttr.Configure(prop); foreach (var attr in prop.GetCustomAttributes().OfType <ValidationAttribute>()) { argument.Validators.Add(new AttributeValidator(attr)); } argument.MultipleValues = prop.PropertyType.IsArray || (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType) && prop.PropertyType != typeof(string)); if (argPropOrder.TryGetValue(argumentAttr.Order, out var otherProp)) { throw new InvalidOperationException( Strings.DuplicateArgumentPosition(argumentAttr.Order, prop, otherProp)); } argPropOrder.Add(argumentAttr.Order, prop); argOrder.Add(argumentAttr.Order, argument); var setter = ReflectionHelper.GetPropertySetter(prop); if (argument.MultipleValues) { convention.Application.OnParsingComplete(r => { var collectionParser = CollectionParserProvider.Default.GetParser( prop.PropertyType, convention.Application.ValueParsers); if (collectionParser == null) { throw new InvalidOperationException(Strings.CannotDetermineParserType(prop)); } if (argument.Values.Count == 0) { return; } if (r.SelectedCommand is IModelAccessor cmd) { setter.Invoke(cmd.GetModel(), collectionParser.Parse(argument.Name, argument.Values)); } }); } else { convention.Application.OnParsingComplete(r => { var parser = convention.Application.ValueParsers.GetParser(prop.PropertyType); if (parser == null) { throw new InvalidOperationException(Strings.CannotDetermineParserType(prop)); } if (argument.Values.Count == 0) { return; } if (r.SelectedCommand is IModelAccessor cmd) { setter.Invoke( cmd.GetModel(), parser.Parse( argument.Name, argument.Value, convention.Application.ValueParsers.ParseCulture)); } }); } }