private void AddSubcommandImpl <TSubCommand>(SubcommandAttribute subcommand) where TSubCommand : class, new() { if (App.Commands.Any(c => c.Name.Equals(subcommand.Name, StringComparison.OrdinalIgnoreCase))) { throw new InvalidOperationException(Strings.DuplicateSubcommandName(subcommand.Name)); } var childApp = App.Command(subcommand.Name, subcommand.Configure); var builder = new ReflectionAppBuilder <TSubCommand>(childApp); builder._bindResult = _bindResult; builder.Initialize(); var subcommandProp = typeof(TTarget).GetTypeInfo().GetProperty("Subcommand", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); if (subcommandProp != null) { var setter = ReflectionHelper.GetPropertySetter(subcommandProp); builder.OnBind(o => setter.Invoke(this._target, o)); } var parentProp = subcommand.CommandType.GetTypeInfo().GetProperty("Parent", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); if (parentProp != null) { var setter = ReflectionHelper.GetPropertySetter(parentProp); builder.OnBind(o => setter.Invoke(o, this._target)); } }
private void AddRemainingArgsProperty(TypeInfo typeInfo) { var prop = typeInfo.GetProperty("RemainingArguments", PropertyBindingFlags); prop = prop ?? typeInfo.GetProperty("RemainingArgs", PropertyBindingFlags); if (prop == null) { return; } var setter = ReflectionHelper.GetPropertySetter(prop); if (prop.PropertyType == typeof(string[])) { OnBind(o => setter(o, App.RemainingArguments.ToArray())); return; } if (!typeof(IReadOnlyList <string>).GetTypeInfo().IsAssignableFrom(prop.PropertyType)) { throw new InvalidOperationException(Strings.RemainingArgsPropsIsUnassignable(typeInfo)); } OnBind(o => setter(o, App.RemainingArguments)); }
private void AddArgument(PropertyInfo prop, ArgumentAttribute argumentAttr) { 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).GetTypeInfo().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) { var collectionParser = CollectionParserProvider.Default.GetParser(prop.PropertyType); if (collectionParser == null) { throw new InvalidOperationException(Strings.CannotDetermineParserType(prop)); } OnBind(o => setter.Invoke(o, collectionParser.Parse(argument.Name, argument.Values))); } else { var parser = ValueParserProvider.Default.GetParser(prop.PropertyType); if (parser == null) { throw new InvalidOperationException(Strings.CannotDetermineParserType(prop)); } OnBind(o => setter.Invoke(o, parser.Parse(argument.Name, argument.Value))); } }
private void AddSubcommandImpl <TSubCommand>(Type parent, SubcommandAttribute subcommand) where TSubCommand : class, new() { var parentApp = App; var childApp = App.Command(subcommand.Name, subcommand.Configure); var builder = new ReflectionAppBuilder <TSubCommand>(childApp); builder.Initialize(); var subcommandProp = parent.GetTypeInfo().GetProperty("Subcommand", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); if (subcommandProp != null) { var setter = ReflectionHelper.GetPropertySetter(subcommandProp); builder.OnBind(o => { if (parentApp.State is BindContext ctx) { setter.Invoke(ctx.Target, o); } }); } var parentProp = subcommand.CommandType.GetTypeInfo().GetProperty("Parent", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); if (parentProp != null) { var setter = ReflectionHelper.GetPropertySetter(parentProp); builder.OnBind(o => { if (parentApp.State is BindContext ctx) { setter.Invoke(o, ctx.Target); } }); } }
private void AddOption(OptionAttributeBase optionAttr, PropertyInfo prop) { CommandOption option; switch (optionAttr) { case HelpOptionAttribute h: option = h.Configure(App); break; case OptionAttribute o: option = o.Configure(App, prop); break; case VersionOptionAttribute v: option = v.Configure(App); break; default: throw new ArgumentOutOfRangeException(); } foreach (var attr in prop.GetCustomAttributes().OfType <ValidationAttribute>()) { option.Validators.Add(new AttributeValidator(attr)); } if (option.OptionType == CommandOptionType.NoValue && prop.PropertyType != typeof(bool)) { throw new InvalidOperationException(Strings.NoValueTypesMustBeBoolean); } if (option.ShortName != null) { if (_shortOptions.TryGetValue(option.ShortName, out var otherProp)) { throw new InvalidOperationException( Strings.OptionNameIsAmbiguous(option.ShortName, prop, otherProp)); } _shortOptions.Add(option.ShortName, prop); } if (option.LongName != null) { if (_longOptions.TryGetValue(option.LongName, out var otherProp)) { throw new InvalidOperationException( Strings.OptionNameIsAmbiguous(option.LongName, prop, otherProp)); } _longOptions.Add(option.LongName, prop); } var setter = ReflectionHelper.GetPropertySetter(prop); switch (option.OptionType) { case CommandOptionType.MultipleValue: var collectionParser = CollectionParserProvider.Default.GetParser(prop.PropertyType); if (collectionParser == null) { throw new InvalidOperationException(Strings.CannotDetermineParserType(prop)); } OnBind(o => setter.Invoke(o, collectionParser.Parse(option.LongName, option.Values))); break; case CommandOptionType.SingleValue: var parser = ValueParserProvider.Default.GetParser(prop.PropertyType); if (parser == null) { throw new InvalidOperationException(Strings.CannotDetermineParserType(prop)); } OnBind(o => { var value = option.Value(); if (value == null) { return; } setter.Invoke(o, parser.Parse(option.LongName, value)); }); break; case CommandOptionType.NoValue: OnBind(o => setter.Invoke(o, option.HasValue())); break; default: throw new ArgumentOutOfRangeException(); } }