public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var valueOfProperty = new Dictionary <PropertyInfo, object>(); var namedPropertiesMapping = GetNamedProperties(options, GetProperties(typeToConvert)); reader.Read(); while (true) { if (reader.TokenType != JsonTokenType.PropertyName && reader.TokenType != JsonTokenType.String) { break; } var jsonPropName = reader.GetString(); var normalizedPropName = ConvertAndNormalizeName(jsonPropName, options); if (!namedPropertiesMapping.TryGetValue(normalizedPropName, out var obProp)) { reader.Read(); } else { var value = JsonSerializer.Deserialize(ref reader, obProp.PropertyType, options); reader.Read(); valueOfProperty[obProp] = value; } } var ctor = typeToConvert.GetConstructors(BindingFlags.Public | BindingFlags.Instance).First(); var parameters = ctor.GetParameters(); var parameterValues = new object[parameters.Length]; for (var index = 0; index < parameters.Length; index++) { var parameterInfo = parameters[index]; var value = valueOfProperty.First(prop => NameOfPropertyAndParameter.Matches(prop.Key.Name, parameterInfo.Name)).Value; parameterValues[index] = value; } var instance = ctor.Invoke(parameterValues); return(instance); }
public override bool CanConvert(Type typeToConvert) { bool result; var constructors = typeToConvert.GetConstructors(BindingFlags.Public | BindingFlags.Instance); if (constructors.Length != 1) { result = false; } else { var constructor = constructors[0]; var parameters = constructor.GetParameters(); var hasParameters = parameters.Length > 0; if (hasParameters) { var properties = typeToConvert.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); result = true; foreach (var parameter in parameters) { var hasMatchingProperty = properties.Any(p => NameOfPropertyAndParameter.Matches(p.Name, parameter.Name)); if (!hasMatchingProperty) { result = false; break; } } } else { result = false; } } return(result); }