using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; namespace WxOrder.Framework.Commons.Dialogs { /// /// Extension methods for Navigation or Dialog parameters /// [EditorBrowsable(EditorBrowsableState.Never)] public static class ParametersExtensions { /// /// Searches for /// /// The type of the parameter to return /// A collection of parameters to search /// The key of the parameter to find /// A matching value of if it exists [EditorBrowsable(EditorBrowsableState.Never)] public static T GetValue(this IEnumerable> parameters, string key) => (T)GetValue(parameters, key, typeof(T)); /// /// Searches for value referenced by /// /// A collection of parameters to search /// The key of the parameter to find /// The type of the parameter to return /// A matching value of if it exists /// Unable to convert the value of Type [EditorBrowsable(EditorBrowsableState.Never)] public static object GetValue(this IEnumerable> parameters, string key, Type type) { foreach (var kvp in parameters) { if (string.Compare(kvp.Key, key, StringComparison.Ordinal) == 0) { if (TryGetValueInternal(kvp, type, out var value)) return value; throw new InvalidCastException($"Unable to convert the value of Type '{kvp.Value.GetType().FullName}' to '{type.FullName}' for the key '{key}' "); } } return GetDefault(type); } /// /// Searches for value referenced by /// /// The type of the parameter to return /// A collection of parameters to search /// The key of the parameter to find /// The value of parameter to return /// Success if value is found; otherwise returns false [EditorBrowsable(EditorBrowsableState.Never)] public static bool TryGetValue(this IEnumerable> parameters, string key, out T value) { var type = typeof(T); foreach (var kvp in parameters) { if (string.Compare(kvp.Key, key, StringComparison.Ordinal) == 0) { var success = TryGetValueInternal(kvp, typeof(T), out object valueAsObject); value = (T)valueAsObject; return success; } } value = default; return false; } /// /// Searches for value referenced by /// /// The type of the parameter to return /// A collection of parameters to search /// The key of the parameter to find /// An IEnumerable{T} of all the values referenced by key [EditorBrowsable(EditorBrowsableState.Never)] public static IEnumerable GetValues(this IEnumerable> parameters, string key) { List values = new List(); var type = typeof(T); foreach (var kvp in parameters) { if (string.Compare(kvp.Key, key, StringComparison.Ordinal) == 0) { TryGetValueInternal(kvp, type, out var value); values.Add((T)value); } } return values.AsEnumerable(); } private static bool TryGetValueInternal(KeyValuePair kvp, Type type, out object value) { value = GetDefault(type); var success = false; if (kvp.Value == null) { success = true; } else if (kvp.Value.GetType() == type) { success = true; value = kvp.Value; } else if (type.IsAssignableFrom(kvp.Value.GetType())) { success = true; value = kvp.Value; } else if (type.IsEnum) { var valueAsString = kvp.Value.ToString(); if (Enum.IsDefined(type, valueAsString)) { success = true; value = Enum.Parse(type, valueAsString); } else if (int.TryParse(valueAsString, out var numericValue)) { success = true; value = Enum.ToObject(type, numericValue); } } if (!success && type.GetInterface("System.IConvertible") != null) { success = true; value = Convert.ChangeType(kvp.Value, type); } return success; } /// /// Checks to see if key exists in parameter collection /// /// IEnumerable to search /// The key to search the for existence /// true if key exists; false otherwise [EditorBrowsable(EditorBrowsableState.Never)] public static bool ContainsKey(this IEnumerable> parameters, string key) => parameters.Any(x => string.Compare(x.Key, key, StringComparison.Ordinal) == 0); private static object GetDefault(Type type) { if (type.IsValueType) { return Activator.CreateInstance(type); } return null; } } }