/// <summary> /// Deserializes the members. /// </summary> /// <param name="context">The context.</param> /// <returns>The deserialized list of member values.</returns> protected virtual List <MemberValue> DeserializeMembers(ISerializationContext <TSerializationContext> context) { ApiCop.UpdateRule <InitializationApiCopRule>("SerializerBase.WarmupAtStartup", x => x.SetInitializationMode(InitializationMode.Lazy, GetType().GetSafeFullName())); var deserializedMemberValues = new List <MemberValue>(); var serializerModifiers = SerializationManager.GetSerializerModifiers(context.ModelType).Reverse(); var membersToDeserialize = GetSerializableMembers(context.Model); foreach (var member in membersToDeserialize) { var memberSerializationEventArgs = new MemberSerializationEventArgs(context, member); DeserializingMember.SafeInvoke(this, memberSerializationEventArgs); BeforeDeserializeMember(context, member); var serializationObject = DeserializeMember(context, member); if (serializationObject.IsSuccessful) { // Note that we need to sync the member values every time var memberValue = new MemberValue(member.MemberGroup, member.ModelType, member.Type, member.Name, serializationObject.MemberValue); member.Value = memberValue.Value; deserializedMemberValues.Add(memberValue); foreach (var serializerModifier in serializerModifiers) { serializerModifier.DeserializeMember(context, member); memberValue.Value = member.Value; } AfterDeserializeMember(context, member); memberValue.Value = member.Value; DeserializedMember.SafeInvoke(this, memberSerializationEventArgs); memberValue.Value = member.Value; } } if (deserializedMemberValues.Count > 0) { PopulateModel(context.Model, deserializedMemberValues.ToArray()); } return(deserializedMemberValues); }
/// <summary> /// Deserializes the members. /// </summary> /// <param name="context">The context.</param> /// <returns>The deserialized list of member values.</returns> protected virtual List <MemberValue> DeserializeMembers(ISerializationContext <TSerializationContext> context) { ApiCop.UpdateRule <InitializationApiCopRule>("SerializerBase.WarmupAtStartup", x => x.SetInitializationMode(InitializationMode.Lazy, GetType().GetSafeFullName(false))); var deserializedMemberValues = new List <MemberValue>(); var serializerModifiers = SerializationManager.GetSerializerModifiers(context.ModelType).Reverse(); var membersToDeserialize = GetSerializableMembers(context, context.Model); foreach (var member in membersToDeserialize) { var memberSerializationEventArgs = new MemberSerializationEventArgs(context, member); DeserializingMember.SafeInvoke(this, memberSerializationEventArgs); BeforeDeserializeMember(context, member); var serializationObject = DeserializeMember(context, member); if (serializationObject.IsSuccessful) { // Note that we need to sync the member values every time var memberValue = new MemberValue(member.MemberGroup, member.ModelType, member.MemberType, member.Name, member.NameForSerialization, serializationObject.MemberValue); if (memberValue.MemberGroup == SerializationMemberGroup.Dictionary) { var targetDictionary = TypeFactory.CreateInstance(member.MemberType) as IDictionary; if (targetDictionary == null) { throw Log.ErrorAndCreateException <NotSupportedException>("'{0}' seems to be a dictionary, but target model cannot be updated because it does not implement IDictionary", context.ModelTypeName); } var enumerable = memberValue.Value as List <SerializableKeyValuePair>; if (enumerable != null) { foreach (var item in enumerable) { targetDictionary.Add(item.Key, item.Value); } } else { var sourceDictionary = memberValue.Value as IDictionary; if (sourceDictionary != null) { foreach (var key in sourceDictionary.Keys) { targetDictionary.Add(key, sourceDictionary[key]); } } } member.Value = targetDictionary; } else if (memberValue.MemberGroup == SerializationMemberGroup.Collection) { var sourceCollection = memberValue.Value as IEnumerable; if (member.MemberType.IsArrayEx()) { var elementType = member.MemberType.GetElementTypeEx(); member.Value = sourceCollection.ToArray(elementType); } else { var targetCollection = TypeFactory.CreateInstance(member.MemberType) as IList; if (targetCollection == null) { throw Log.ErrorAndCreateException <NotSupportedException>("'{0}' seems to be a collection, but target model cannot be updated because it does not implement IList", context.ModelTypeName); } if (sourceCollection != null) { foreach (var item in sourceCollection) { targetCollection.Add(item); } } member.Value = targetCollection; } } else { member.Value = memberValue.Value; } deserializedMemberValues.Add(memberValue); foreach (var serializerModifier in serializerModifiers) { serializerModifier.DeserializeMember(context, member); memberValue.Value = member.Value; } AfterDeserializeMember(context, member); memberValue.Value = member.Value; DeserializedMember.SafeInvoke(this, memberSerializationEventArgs); memberValue.Value = member.Value; } } if (deserializedMemberValues.Count > 0) { var firstMember = deserializedMemberValues[0]; if (firstMember.MemberGroup == SerializationMemberGroup.SimpleRootObject) { // Completely replace root object (this is a basic (non-reference) type) context.Model = firstMember.Value; } else if (firstMember.MemberGroup == SerializationMemberGroup.Dictionary) { var targetDictionary = context.Model as IDictionary; if (targetDictionary == null) { throw Log.ErrorAndCreateException <NotSupportedException>("'{0}' seems to be a dictionary, but target model cannot be updated because it does not implement IDictionary", context.ModelTypeName); } targetDictionary.Clear(); var sourceDictionary = firstMember.Value as IDictionary; if (sourceDictionary != null) { foreach (var key in sourceDictionary.Keys) { targetDictionary.Add(key, sourceDictionary[key]); } } } else if (firstMember.MemberGroup == SerializationMemberGroup.Collection) { if (context.ModelType.IsArrayEx()) { context.Model = firstMember.Value; } else { var targetCollection = context.Model as IList; if (targetCollection == null) { throw Log.ErrorAndCreateException <NotSupportedException>("'{0}' seems to be a collection, but target model cannot be updated because it does not implement IList", context.ModelTypeName); } targetCollection.Clear(); var sourceCollection = firstMember.Value as IEnumerable; if (sourceCollection != null) { foreach (var item in sourceCollection) { targetCollection.Add(item); } } } } else { PopulateModel(context.Model, deserializedMemberValues.ToArray()); } } return(deserializedMemberValues); }
/// <summary> /// Ends member deserialization by invoking all the right events and running the modifiers. /// </summary> /// <param name="context">The serialization context.</param> /// <param name="member">The member that has been deserialized.</param> /// <param name="serializationObject">Result of the member deserialization.</param> /// <param name="serializerModifiers">The serializer modifiers.</param> protected virtual MemberValue EndMemberDeserialization(ISerializationContext <TSerializationContextInfo> context, MemberValue member, SerializationObject serializationObject, IEnumerable <ISerializerModifier> serializerModifiers) { if (!serializationObject.IsSuccessful) { return(null); } // Note that we need to sync the member values every time var memberValue = new MemberValue(member.MemberGroup, member.ModelType, member.MemberType, member.Name, member.NameForSerialization, serializationObject.MemberValue); if (memberValue.MemberGroup == SerializationMemberGroup.Dictionary || ShouldSerializeAsDictionary(member)) { var targetDictionary = TypeFactory.CreateInstance(member.MemberType) as IDictionary; if (targetDictionary is null) { throw Log.ErrorAndCreateException <NotSupportedException>("'{0}' seems to be a dictionary, but target model cannot be updated because it does not implement IDictionary", context.ModelTypeName); } var enumerable = memberValue.Value as List <SerializableKeyValuePair>; if (enumerable != null) { foreach (var item in enumerable) { targetDictionary.Add(item.Key, item.Value); } } else { var sourceDictionary = memberValue.Value as IDictionary; if (sourceDictionary != null) { foreach (var key in sourceDictionary.Keys) { targetDictionary.Add(key, sourceDictionary[key]); } } } member.Value = targetDictionary; } else if (memberValue.MemberGroup == SerializationMemberGroup.Collection) { var sourceCollection = memberValue.Value as IEnumerable; if (member.MemberType.IsArrayEx()) { var elementType = member.MemberType.GetElementTypeEx(); member.Value = sourceCollection.ToArray(elementType); } else { var targetCollection = TypeFactory.CreateInstance(member.MemberType) as IList; if (targetCollection is null) { throw Log.ErrorAndCreateException <NotSupportedException>("'{0}' seems to be a collection, but target model cannot be updated because it does not implement IList", context.ModelTypeName); } if (sourceCollection != null) { foreach (var item in sourceCollection) { targetCollection.Add(item); } } member.Value = targetCollection; } } else { member.Value = memberValue.Value; } foreach (var serializerModifier in serializerModifiers) { serializerModifier.DeserializeMember(context, member); memberValue.Value = member.Value; } AfterDeserializeMember(context, member); memberValue.Value = member.Value; DeserializedMember?.Invoke(this, new MemberSerializationEventArgs(context, member)); memberValue.Value = member.Value; return(memberValue); }