private static string GetCommandDescription(Type type, string commandName) { if (type == null) { throw new ArgumentNullException("type"); } if (commandName == null) { throw new ArgumentNullException("commandName"); } var result = new StringBuilder(); var basePadding = 1; foreach (var method in type.GetTypeInfo().GetAllMethods().Where(IsValidCommandSignature)) { if (string.Equals(method.Name, commandName, StringComparison.OrdinalIgnoreCase) == false) { continue; } if (IsHidden(method)) { continue; } result.Append(' ', basePadding).AppendLine("Command:"); result.Append(' ', basePadding + 1).Append(method.Name.ToUpper()).Append(" "); var paramsArr = method.GetParameters().Where(p => !IsHidden(p)).Select(parameter => string.Format(parameter.IsOptional ? "[--{0} <{1}>] " : "--{0} <{1}> ", parameter.Name, GetParameterTypeFriendlyName(parameter))).ToArray(); var paramsDesc = string.Concat(paramsArr); AppendLinePadded(result, paramsDesc); result.AppendLine(); var methodDescriptionText = default(string); var methodHelpText = method.GetCustomAttributes(typeof(HelpTextAttribute), true).Cast <HelpTextAttribute>().FirstOrDefault(); if (methodHelpText != null) { methodDescriptionText = methodHelpText.Description; } #if !NETSTANDARD1_3 var methodDescription = method.GetCustomAttributes(typeof(DescriptionAttribute), true).Cast <DescriptionAttribute>().FirstOrDefault(); if (methodDescription != null) { methodDescriptionText = methodDescriptionText ?? methodDescription.Description; } #endif methodDescriptionText = (methodDescriptionText ?? string.Empty).Trim(); if (string.IsNullOrEmpty(methodDescriptionText) == false) { result.Append(' ', basePadding).AppendLine("Description:"); result.Append(' ', basePadding + 1); if (methodDescriptionText.EndsWith(".", StringComparison.OrdinalIgnoreCase) == false) { methodDescriptionText += "."; } AppendLinePadded(result, methodDescriptionText); } else { result.AppendLine(); } result.AppendLine(); result.Append(' ', basePadding).AppendLine("Parameters:"); foreach (var parameter in method.GetParameters()) { if (IsHidden(parameter)) { continue; } if (parameter.ParameterType == typeof(CommandLineArguments)) { continue; } var parameterType = Nullable.GetUnderlyingType(parameter.ParameterType) ?? parameter.ParameterType; var parameterTypeName = parameterType.Name; var options = ""; var defaultValue = ""; if (parameterType.GetTypeInfo().IsEnum) { options = " Options are " + string.Join(", ", Enum.GetNames(parameterType)) + "."; } if (parameter.IsOptional && parameter.DefaultValue != null) { defaultValue = " Default value is '" + TypeConvert.Convert(parameter.DefaultValue, parameterType) + "'."; } var paramDescriptionText = default(string); var paramHelpText = parameter.GetCustomAttributes(typeof(HelpTextAttribute), true).Cast <HelpTextAttribute>().FirstOrDefault(); if (paramHelpText != null) { paramDescriptionText = paramHelpText.Description; } #if !NETSTANDARD1_3 var paramDescription = parameter.GetCustomAttributes(typeof(DescriptionAttribute), true).Cast <DescriptionAttribute>().FirstOrDefault(); if (paramDescription != null) { paramDescriptionText = paramDescriptionText ?? paramDescription.Description; } #endif paramDescriptionText = (paramDescriptionText ?? string.Empty).Trim(); if (paramDescriptionText.Length > 0 && paramDescriptionText.EndsWith(".", StringComparison.OrdinalIgnoreCase) == false) { paramDescriptionText += "."; } result.Append(' ', basePadding + 2); result.Append(parameter.Name.ToUpperInvariant()).Append(" "); AppendLinePadded(result, string.Format("({0}) {1}{2}{3}", parameterTypeName, paramDescriptionText ?? string.Empty, defaultValue, options)); } } return(result.ToString()); }
private static ParameterBindResult BindParameter(ParameterInfo parameter, CommandLineArguments arguments) { var expectedType = parameter.ParameterType; var value = default(object); try { if (expectedType == typeof(CommandLineArguments)) { value = new CommandLineArguments(arguments); } else if (arguments.TryGetValue(parameter.Name, out value) || arguments.TryGetValue((parameter.Position).ToString(), out value)) { if (expectedType.IsArray) { var elemType = expectedType.GetElementType(); Debug.Assert(elemType != null, "elemType != null"); if (value is IList <string> ) { var valuesStr = (IList <string>)value; var values = Array.CreateInstance(elemType, valuesStr.Count); for (var i = 0; i < valuesStr.Count; i++) { value = valuesStr[i]; // used on failure in exception block values.SetValue(Convert(valuesStr[i], elemType, parameter), i); } value = values; } else if (value != null) { var values = Array.CreateInstance(elemType, 1); values.SetValue(Convert(value, elemType, parameter), 0); value = values; } else { var values = Array.CreateInstance(elemType, 0); value = values; } } else if (expectedType == typeof(bool) && value == null) { value = true; } else if (value == null) { value = parameter.IsOptional ? parameter.DefaultValue : expectedType.GetTypeInfo().IsValueType ? TypeActivator.CreateInstance(expectedType) : null; } else if (expectedType.GetTypeInfo().IsEnum&& value is IList <string> ) { var valuesStr = (IList <string>)value; var values = new object[valuesStr.Count]; for (var i = 0; i < valuesStr.Count; i++) { value = valuesStr[i]; // used on failure in exception block values[i] = Convert(value, expectedType, parameter); } if (IsSigned(Enum.GetUnderlyingType(expectedType))) { var combinedValue = 0L; foreach (var enumValue in values) { value = enumValue; // used on failure in exception block combinedValue |= (long)TypeConvert.Convert(value, typeof(long)); } value = Enum.ToObject(expectedType, combinedValue); } else { var combinedValue = 0UL; foreach (var enumValue in values) { value = enumValue; // used on failure in exception block combinedValue |= (ulong)TypeConvert.Convert(enumValue, typeof(ulong)); } value = Enum.ToObject(expectedType, combinedValue); } } else if (value is IList <string> && expectedType.GetTypeInfo().IsAssignableFrom(typeof(IList <string>).GetTypeInfo()) == false) { throw new FormatException(string.Format("Parameter has {0} values while only one is expected.", ((IList <string>)value).Count)); } else { value = Convert(value, expectedType, parameter); } } else if (parameter.IsOptional) { value = parameter.DefaultValue; } else if (expectedType == typeof(bool)) { value = false; } else { throw new InvalidOperationException("Missing parameter value."); } } catch (Exception bindingError) { return(new ParameterBindResult(parameter, bindingError, value)); } if (value != null && value.GetType() != parameter.ParameterType) { value = TypeConvert.Convert(value, parameter.ParameterType); } return(new ParameterBindResult(parameter, null, value)); }
private static bool TryBindParameter(ParameterInfo parameter, CommandLineArguments arguments, out object value) { var expectedType = parameter.ParameterType; if (expectedType == typeof(CommandLineArguments)) { value = new CommandLineArguments(arguments); } else if (arguments.TryGetValue(parameter.Name, out value) || arguments.TryGetValue((parameter.Position).ToString(), out value)) { if (expectedType.IsArray) { var elemType = expectedType.GetElementType(); Debug.Assert(elemType != null, "elemType != null"); if (value is string[]) { var oldArr = value as string[]; var newArr = Array.CreateInstance(elemType, oldArr.Length); for (var v = 0; v < oldArr.Length; v++) { newArr.SetValue(TypeConvert.Convert(typeof(string), elemType, oldArr[v]), v); } value = newArr; } else if (value != null) { var newArr = Array.CreateInstance(elemType, 1); newArr.SetValue(TypeConvert.Convert(value.GetType(), elemType, value), 0); value = newArr; } else { var newArr = Array.CreateInstance(elemType, 0); value = newArr; } } else if (expectedType == typeof(bool) && value == null) { value = true; } else if (value == null) { value = parameter.IsOptional ? parameter.DefaultValue : expectedType.IsValueType ? TypeActivator.CreateInstance(expectedType) : null; } else if (expectedType.IsEnum && value is string[]) { var valuesStr = (string[])value; var values = Array.ConvertAll(valuesStr, v => TypeConvert.Convert(typeof(string), expectedType, v)); if (IsSigned(Enum.GetUnderlyingType(expectedType))) { var combinedValue = 0L; foreach (var v in values) { combinedValue |= (long)TypeConvert.Convert(expectedType, typeof(long), v); } value = Enum.ToObject(expectedType, combinedValue); } else { var combinedValue = 0UL; foreach (var v in values) { combinedValue |= (ulong)TypeConvert.Convert(expectedType, typeof(ulong), v); } value = Enum.ToObject(expectedType, combinedValue); } } else { value = TypeConvert.Convert(value.GetType(), expectedType, value); } } else if (parameter.IsOptional) { value = parameter.DefaultValue; } else if (expectedType == typeof(bool)) { value = false; } else { return(false); } return(true); }