Esempio n. 1
0
        /// <summary>
        /// Adds the supplied <see cref="AttributeField"/> to the <see cref="ArgumentDictionary"/>.
        /// </summary>
        /// <param name="attr">The <see cref="ArgumentAttribute"/> to use the <see cref="ArgumentAttribute.LongName"/> or <see cref="AttributeField.Attr.ShortName"/> of.</param>
        /// <param name="fields">The <see cref="AttributeField"/> to add to the <see cref="ArgumentDictionary"/>.</param>
        public void Add(ArgumentAttribute attr, AttributeField field)
        {
            if (this.innerContainer.ContainsKey(attr.LongName))
            {
                this.innerContainer[attr.LongName].Add(field);
            }
            else
            {
                this.innerContainer.Add(attr.LongName, new List <AttributeField> {
                    field
                });
            }

            if (this.innerContainer.ContainsKey(attr.ShortName))
            {
                this.innerContainer[attr.ShortName].Add(field);
            }
            else
            {
                this.innerContainer.Add(attr.ShortName, new List <AttributeField> {
                    field
                });
            }

            this.cachedValues = null;
        }
Esempio n. 2
0
 /// <summary>
 /// For the specified <see cref="AttributeField"/> <paramref name="field"/>, for all instances in the <paramref name="instanceSource"/>, set the associated field to the supplied <paramref name="value"/>.
 /// </summary>
 /// <param name="value">The value to use for the <paramref name="field"/>'s new value.</param>
 /// <param name="field">The <see cref="AttributeField"/> to target - instances in <paramref name="instanceSource"/> will have their value changed for this field.</param>
 /// <param name="instanceSource">The instances upon which to change the associated fields values.</param>
 private static void SetInstanceFieldValue(
     string value,
     AttributeField field,
     IEnumerable <object> instanceSource)
 {
     foreach (object instance in
              instanceSource.Where(x => x.GetType().GetFields(Context.bindingFlags).Contains(field.Field)))
     {
         field.Field.SetValue(instance, Convert.ChangeType(value, field.Field.FieldType));
     }
 }
Esempio n. 3
0
        /// <summary>
        /// Invokes the <see cref="Context"/>, initializing any objects in <see cref="Context.Instances"/> with the appropriate values.
        /// </summary>
        /// <param name="mode">Controls the scope of the invocation. View <see cref="ControlModes"/> for information on what these do.</param>
        public static void Invoke(ControlModes mode = ControlModes.RegisteredTypesOnly)
        {
            if (Context.Invoked)
            {
                throw new InvalidOperationException("Cannot invoke multiple times.");
            }

            if (mode == ControlModes.RegisteredTypesOnly)
            {
                Context.fields = new Lazy <ArgumentDictionary>(() =>
                                                               Context.Iterate(
                                                                   Context.Instances
                                                                   .Select(x => x.GetType())
                                                                   .Distinct()));
            }

            IEnumerable <string> alreadyUsedNames =
                Context.manualArguments
                .Where(x => fields.Value.ContainsKey(x.LongName))
                .Select(x => x.LongName)
                .Concat(
                    Context.manualArguments
                    .Where(x => fields.Value.ContainsKey(x.ShortName))
                    .Select(x => x.ShortName));

            if (alreadyUsedNames.Any())
            {
                throw new InvalidOperationException(
                          $"ArgumentGroup contained argument names already in use: {string.Join(", ", alreadyUsedNames)}");
            }

            Context.SetInstanceFieldValues(Context.Fields, Context.Instances);

            List <IArgument> userSupplied =
                Context.manualArguments.Invoke(Context.ParsedArgs).ToList();

            foreach (TreeNode <string> argument in
                     Context.ParsedArgs.Root.Children.Where(x =>
                                                            !userSupplied.Any(y => x.Value == y.LongName || x.Value == y.ShortName)))
            {
                if (fields.Value.ContainsKey(argument.Value))
                {
                    IEnumerable <AttributeField> currentPosition = fields.Value[argument.Value];
                    if (currentPosition.Count() == 1 &&                 // There is a single expected field for that attribute.
                        currentPosition.First().Attr.Position == -1 &&  // The only expected field is a flag.
                        argument.Children.Count == 0)                   // No value was supplied for the field.
                    {
                        Context.SetInstanceFieldValue(
                            "True",
                            currentPosition.First(),
                            Context.Instances);

                        userSupplied.Add(currentPosition.First().Attr);
                    }
                    else if (currentPosition.Count() == argument.Children.Count)
                    {
                        for (int counter = 0; counter < argument.Children.Count; counter++)
                        {
                            AttributeField currentField = currentPosition.ElementAt(counter);
                            Context.SetInstanceFieldValue(
                                argument.Children[counter].Value,
                                currentField,
                                Context.Instances);

                            userSupplied.Add(currentField.Attr);
                        }
                    }
                    else
                    {
                        throw new ArgumentException($"Malformed argument \"{argument.Value}\".");
                    }
                }
                else
                {
                    throw new ArgumentException($"Unrecognized argument \"{argument.Value}\".");
                }
            }

            IArgument[] remainingArguments =
                Context.Fields
                .Select(x => (IArgument)x.Attr)
                .Concat(Context.manualArguments)
                .Except(userSupplied)
                .ToArray();

            if (remainingArguments.Any(x => x.Required))
            {
                IEnumerable <string> missingRequiredArguments =
                    remainingArguments
                    .Where(x => x.Required)
                    .Select(x => $"{x.ShortName} ({x.LongName})");

                throw new ArgumentException(
                          $"Missing required arguments: {string.Join(", ", missingRequiredArguments)}");
            }

            Context.Invoked = true;
        }