예제 #1
0
        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();
            }
        }