diff --git a/attributes/ReflectedAttribute.cs b/attributes/ReflectedAttribute.cs new file mode 100644 index 0000000..eda20d5 --- /dev/null +++ b/attributes/ReflectedAttribute.cs @@ -0,0 +1,10 @@ +using System; +namespace ln.json.attributes +{ + public class ReflectedAttribute : Attribute + { + public ReflectedAttribute() + { + } + } +} diff --git a/ln.json.csproj b/ln.json.csproj index 5d01174..f6873ba 100644 --- a/ln.json.csproj +++ b/ln.json.csproj @@ -56,6 +56,7 @@ + diff --git a/mapping/JSONEnumerableMapping.cs b/mapping/JSONEnumerableMapping.cs index 0920eb6..b88f96b 100644 --- a/mapping/JSONEnumerableMapping.cs +++ b/mapping/JSONEnumerableMapping.cs @@ -17,9 +17,9 @@ namespace ln.json.mapping Type elementType; public JSONEnumerableMapping() - : base(typeof(T)) + : base(typeof(IEnumerable)) { - elementType = typeof(T).GetGenericArguments()[0]; + elementType = typeof(T); } public override object FromJson(JSONMapper mapper, JSONValue json) diff --git a/mapping/JSONMapper.cs b/mapping/JSONMapper.cs index 52ccf83..1d6ecec 100644 --- a/mapping/JSONMapper.cs +++ b/mapping/JSONMapper.cs @@ -12,6 +12,7 @@ using System.Reflection; using System.Collections.Generic; using System.Collections; using System.Diagnostics.Tracing; +using ln.types.reflection; namespace ln.json.mapping { public class JSONMapper @@ -149,9 +150,12 @@ namespace ln.json.mapping else if (targetType.IsGenericType) { Type genericTypeDefinition = targetType.GetGenericTypeDefinition(); - if (genericTypeDefinition.Equals(typeof(IEnumerable<>))) + if (targetType.HasGenericInterface(typeof(IEnumerable<>))) { - Add((JSONMapping)Activator.CreateInstance(typeof(JSONEnumerableMapping<>).MakeGenericType(targetType.GetGenericArguments()[0]))); + targetType = targetType.GetGenericInterface(typeof(IEnumerable<>)); + if (!mappings.ContainsKey(targetType)) + Add((JSONMapping)Activator.CreateInstance(typeof(JSONEnumerableMapping<>).MakeGenericType(targetType.GetGenericArguments()[0]))); + } else if (genericTypeDefinition.Equals(typeof(Dictionary<,>))) { diff --git a/reflection/ObjectPoolContainerSerializer.cs b/reflection/ObjectPoolContainerSerializer.cs index eed434f..2953354 100644 --- a/reflection/ObjectPoolContainerSerializer.cs +++ b/reflection/ObjectPoolContainerSerializer.cs @@ -1,6 +1,7 @@ using System; using ln.types.reflection; using ln.json.mapping; +using ln.types; namespace ln.json.reflection { public class ObjectPoolContainerSerializer @@ -20,9 +21,9 @@ namespace ln.json.reflection { JSONArray objectList = new JSONArray(); - foreach (object o in objectPool.Instances) + foreach (object o in objectPool.OwnInstances) { - objectList.Add(JSONMapper.DefaultMapper.ToJson(o)); + objectList.Add(SerializeObject(objectPool, o)); } serializedPoolContainer.Add(objectPool.ObjectType.Name, objectList); @@ -31,6 +32,26 @@ namespace ln.json.reflection return serializedPoolContainer; } + public JSONObject SerializeObject(ObjectPool objectPool, object o) + { + TypeDescriptor typeDescriptor = objectPool.TypeDescriptor; + JSONObject jObject = new JSONObject(); + + jObject["__origin__"] = o.GetType().Name; + + foreach (AttributeDescriptor attributeDescriptor in typeDescriptor.AttributeDescriptors) + { + object attributeValue = attributeDescriptor.GetValue(o); + if (ObjectPoolContainer.KnowsType(attributeDescriptor.AttributeType)) + { + attributeValue = ObjectPoolContainer[attributeDescriptor.AttributeType].GetIdentity(attributeValue); + } + jObject.Add(attributeDescriptor.AttributeName, JSONMapper.DefaultMapper.ToJson(attributeValue)); + } + return jObject; + } + + public void Unserialize(JSONObject serializedPoolContainer) { foreach (ObjectPool objectPool in ObjectPoolContainer.Pools) @@ -40,10 +61,49 @@ namespace ln.json.reflection JSONArray serializedObjects = serializedPoolContainer[objectPool.ObjectType.Name] as JSONArray; foreach (JSONObject serializedObject in serializedObjects.Children) { - objectPool.Add(JSONMapper.DefaultMapper.FromJson(serializedObject, objectPool.ObjectType)); + objectPool.Add(UnserializeObject(objectPool, serializedObject)); } } } } + + public object UnserializeObject(ObjectPool objectPool, JSONObject jObject) + { + object o = Activator.CreateInstance(objectPool.ObjectType); + + UpdateObject(objectPool, o, jObject); + + return o; + } + + public void UpdateObject(ObjectPool objectPool, object o, JSONObject jObject) + { + TypeDescriptor typeDescriptor = objectPool.TypeDescriptor; + + foreach (AttributeDescriptor attributeDescriptor in typeDescriptor.AttributeDescriptors) + { + if (jObject.ContainsKey(attributeDescriptor.AttributeName)) + ApplyValue(objectPool, attributeDescriptor, o, jObject[attributeDescriptor.AttributeName]); + } + } + + public void ApplyValue(ObjectPool objectPool, AttributeDescriptor attributeDescriptor, object o, JSONValue jValue) + { + object attributeValue; + + if (ObjectPoolContainer.KnowsType(attributeDescriptor.AttributeType)) + { + attributeValue = ObjectPoolContainer[attributeDescriptor.AttributeType][jValue.ToNative()]; + } + else + { + attributeValue = JSONMapper.DefaultMapper.FromJson(jValue, attributeDescriptor.AttributeType); + } + + if (!object.ReferenceEquals(null,attributeValue) && !object.Equals(attributeValue.GetType(), attributeDescriptor.AttributeType)) + attributeValue = Cast.To(attributeValue, attributeDescriptor.AttributeType); + + attributeDescriptor.SetValue(o, attributeValue); + } } }