internal static ConnectionOptions ParseConnectionOptions(object connectionOptions) { DbDoc options; try { options = new DbDoc(connectionOptions); } catch (Exception ex) { throw new ArgumentException(string.Format(ResourcesX.ClientOptionNotValid, "JSON"), ex); } if (options == null || options.values.Count == 0) { throw new ArgumentException(string.Format(ResourcesX.ClientOptionNotValid, connectionOptions)); } ConnectionOptions instance = new ConnectionOptions(); Type optionType = instance.GetType(); foreach (var item in options.values) { PropertyInfo parent = optionType.GetProperty(item.Key, BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase); if (parent == null) { throw new ArgumentException(string.Format(ResourcesX.ClientOptionNotValid, item.Key)); } object target = parent.GetValue(instance); if (parent.DeclaringType.IsNested) { DbDoc children; try { children = new DbDoc(item.Value); } catch (Exception ex) { throw new ArgumentException(string.Format(ResourcesX.ClientOptionInvalidValue, item.Key, "JSON"), ex); } if (children == null || children.values.Count == 0) { throw new ArgumentException(string.Format(ResourcesX.ClientOptionInvalidValue, item.Key, item.Value)); } foreach (var option in children.values) { var key = parent.PropertyType.GetProperty(option.Key, BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase); if (key == null) { throw new ArgumentException(string.Format(ResourcesX.ClientOptionNotValid, $"{item.Key}.{option.Key}")); } try { key.SetValue(target, option.Value); } catch (Exception ex) { object value = option.Value; switch (value) { case MySqlExpression expr: value = ((MySqlExpression)expr).value.Trim(); break; } throw new ArgumentException(string.Format(ResourcesX.ClientOptionInvalidValue, $"{item.Key}.{option.Key}", value), ex); } } } parent.SetValue(instance, target); } return(instance); }