private static T ParseCollection <T>(this IRecord record, string identifier, IGraphClient graphClient) { var typeT = typeof(T).GetTypeInfo(); if (!typeT.IsGenericType && !typeT.IsArray) { throw new InvalidOperationException($"Don't know how to handle {typeof(T).FullName}"); } if (typeT.IsArray) { return(record.ParseArray <T>(identifier, graphClient)); } var genericArgs = typeT.GenericTypeArguments; if (genericArgs.Length > 1) { throw new InvalidOperationException($"Don't know how to handle {typeof(T).FullName}"); } var listType = typeof(List <>).MakeGenericType(genericArgs.Single()); var list = Activator.CreateInstance(listType); foreach (var item in (IEnumerable)record[identifier]) { var internalRecord = new Neo4jClientRecord(item, identifier); var method = GetParsed(genericArgs.Single()); var parsed = method.Invoke(null, internalRecord.AsParameters(graphClient)); listType.GetMethod("Add")?.Invoke(list, new[] { parsed }); } return((T)list); }
private static T Parse <T>(this IRecord record, string identifier, IGraphClient graphClient) { var typeT = typeof(T); if (typeT.IsPrimitive()) { return(record.ParsePrimitive <T>(identifier)); } if (typeT.GetTypeInfo().ImplementedInterfaces.Any(x => x.Name == nameof(IEnumerable)) && typeT.Name != nameof(ExpandoObject)) { return(record.ParseCollection <T>(identifier, graphClient)); } var converters = graphClient.JsonConverters; converters.Reverse(); var serializerSettings = new JsonSerializerSettings { Converters = converters, ContractResolver = graphClient.JsonContractResolver }; foreach (var jsonConverter in converters) { if (jsonConverter.CanConvert(typeof(T))) { return(JsonConvert.DeserializeObject <T>(record[identifier].As <INode>().ToJsonString(), serializerSettings)); } } var t = ConstructNew <T>(); var obj = record[identifier]; if (obj is INode node) { foreach (var property in t.GetType().GetProperties()) { if (node.Properties.ContainsKey(property.Name)) { if (property.PropertyType.IsPrimitive()) { property.SetValue(t, Convert.ChangeType(node.Properties[property.Name], property.PropertyType)); } else if (property.PropertyType.GetTypeInfo().ImplementedInterfaces.Any(i => i == typeof(IEnumerable))) { var parsed = GetParsed(property.PropertyType); var enumRecord = new Neo4jClientRecord(node.Properties[property.Name], "Enumerable"); var list = parsed.Invoke(null, enumRecord.AsParameters(graphClient)); property.SetValue(t, list); } else { var res = JsonConvert.DeserializeObject( $"\"{node.Properties[property.Name].As<string>()}\"", property.PropertyType, serializerSettings); property.SetValue(t, res); } } } } return(t); }