/// <summary> /// Parse the argument string array /// </summary> /// <param name="args">string array comes from commandline, split by windows api</param> /// <param name="argumentObject">the value container of argument</param> /// <remarks> /// ArgumentException would be thrown if the declaration of ArgumentObject is not correct, this should /// be fixed in coding time. /// /// If the declaration is correct, no exception is expected to be raised. /// Check the ArgumentResult and determinte whether the commandline is ok or not. /// </remarks> /// <returns>The result of parsing</returns> public static ArgumentResult ParseArgument(string[] args, IArgumentObject argumentObject) { Debug.Assert(args != null); if (argumentObject == null) { throw new ArgumentException("argument or optionObject cannot be null"); } return(ParseArgumentInternal(args, argumentObject)); }
internal static ArgumentResult ParseArgumentInternal(string[] args, IArgumentObject argumentObject) { // Validate IArgumentObject.Options var options = argumentObject.Options; if (options == null || options.Count == 0) { throw new ArgumentException("IArgumentObject.Options cannot be null or empty"); } if (options.Select(a => a.Key.ToLower()).Distinct().Count() != options.Count) { throw new ArgumentException("IArgumentObject.Options has duplicated option name"); } // Retrieve the attributes from object's properties var optionParameterAttribDic = BuildArguParamAttrDic(options.Keys); foreach (var property in argumentObject.GetType().GetProperties()) { var paramAttrs = property.GetCustomAttributes <ArgumentParameterAttribute>(); if (paramAttrs.Length > 0) // Only validate property with ParameterOptionAttribute { if (!property.PropertyType.IsSupported()) { throw new ArgumentException(string.Format("Property:{0}, the Type:{1} is not supported", property.Name, property.PropertyType.Name)); } foreach (var attr in paramAttrs) { ValidateParameterOptionAttr(property, attr, options); foreach (string option in attr.OptionsBindTo) { if (optionParameterAttribDic[option].ContainsKey(attr.ParameterName)) { throw new ArgumentException(string.Format("option:{0} has multiple setting of parameter:{1}", option, attr.ParameterName)); } optionParameterAttribDic[option].Add(attr.ParameterName, attr); } } } } // Parse system commandline, after this line, no exception is thrown to caller. ArgumentResult ar = new ArgumentResult(); ar.ParamAttributes = optionParameterAttribDic; ar.OptionDescriptions = options; List <KeyValuePair <string, string> > argPairs = null; try { string optionName = ParseArgumentArray(args, out argPairs); if (!optionParameterAttribDic.ContainsKey(optionName)) { throw new ArgumentException("optionName: '" + optionName + "' is not defined in argument object"); } ar.SelectedOptionName = optionName; AssignValuesToArgumentObject(argumentObject, ar.SelectedOptionName, argPairs, optionParameterAttribDic[ar.SelectedOptionName]); } catch (ArgumentException ae) { ar.ErrorMessages.Add(ae.Message); ar.ParseSucceeded = false; return(ar); } ar.ParseSucceeded = true; return(ar); }