public GetSerializerModifiers ( |
||
type | The type. | |
return | ISerializerModifier[] |
/// <summary> /// Serializes the specified model. /// </summary> /// <param name="model">The model.</param> /// <param name="context">The context.</param> public virtual void Serialize(ModelBase model, TSerializationContext context) { Argument.IsNotNull("model", model); Argument.IsNotNull("context", context); using (var finalContext = GetContext(model, context, SerializationContextMode.Serialization)) { var serializerModifiers = SerializationManager.GetSerializerModifiers(finalContext.ModelType); Log.Debug("Using '{0}' serializer modifiers to deserialize type '{1}'", serializerModifiers.Length, finalContext.ModelType.GetSafeFullName()); var serializingEventArgs = new SerializationEventArgs(finalContext); Serializing.SafeInvoke(this, serializingEventArgs); foreach (var serializerModifier in serializerModifiers) { serializerModifier.OnSerializing(finalContext, model); } BeforeSerialization(finalContext); var members = GetSerializableMembers(model); SerializeMembers(finalContext, members); AfterSerialization(finalContext); foreach (var serializerModifier in serializerModifiers) { serializerModifier.OnSerialized(finalContext, model); } Serialized.SafeInvoke(this, serializingEventArgs); } }
/// <summary> /// Returns whether the member value should be serialized as dictionary. /// </summary> /// <param name="memberType">Type of the member.</param> /// <returns><c>true</c> if the member value should be serialized as dictionary, <c>false</c> otherwise.</returns> protected virtual bool ShouldSerializeAsDictionary(Type memberType) { return(_shouldSerializeAsDictionaryCache.GetFromCacheOrFetch(memberType, () => { var serializerModifiers = SerializationManager.GetSerializerModifiers(memberType); if (serializerModifiers != null) { foreach (var serializerModifier in serializerModifiers) { var shouldSerializeAsDictionary = serializerModifier.ShouldSerializeAsDictionary(); if (shouldSerializeAsDictionary.HasValue) { return shouldSerializeAsDictionary.Value; } } } if (memberType.IsDictionary()) { return true; } return false; })); }
/// <summary> /// Serializes the specified model. /// </summary> /// <param name="model">The model.</param> /// <param name="context">The context.</param> protected virtual void Serialize(object model, ISerializationContext <TSerializationContext> context) { Argument.IsNotNull("model", model); Argument.IsNotNull("context", context); var serializerModifiers = SerializationManager.GetSerializerModifiers(context.ModelType); Log.Debug("Using '{0}' serializer modifiers to deserialize type '{1}'", serializerModifiers.Length, context.ModelTypeName); var serializingEventArgs = new SerializationEventArgs(context); Serializing.SafeInvoke(this, serializingEventArgs); foreach (var serializerModifier in serializerModifiers) { serializerModifier.OnSerializing(context, model); } BeforeSerialization(context); var members = GetSerializableMembers(context, model); SerializeMembers(context, members); AfterSerialization(context); foreach (var serializerModifier in serializerModifiers) { serializerModifier.OnSerialized(context, model); } Serialized.SafeInvoke(this, serializingEventArgs); }
/// <summary> /// Serializes the members. /// </summary> /// <param name="context">The context.</param> /// <param name="membersToSerialize">The members to serialize.</param> protected virtual void SerializeMembers(ISerializationContext <TSerializationContext> context, List <MemberValue> membersToSerialize) { ApiCop.UpdateRule <InitializationApiCopRule>("SerializerBase.WarmupAtStartup", x => x.SetInitializationMode(InitializationMode.Lazy, GetType().GetSafeFullName(false))); if (membersToSerialize.Count == 0) { return; } using (GetCurrentSerializationScopeManager(context.Configuration)) { var serializerModifiers = SerializationManager.GetSerializerModifiers(context.ModelType); foreach (var member in membersToSerialize) { bool skipByModifiers = false; foreach (var serializerModifier in serializerModifiers) { if (serializerModifier.ShouldIgnoreMember(context, context.Model, member)) { skipByModifiers = true; break; } } if (skipByModifiers) { continue; } var memberSerializationEventArgs = new MemberSerializationEventArgs(context, member); SerializingMember.SafeInvoke(this, memberSerializationEventArgs); BeforeSerializeMember(context, member); foreach (var serializerModifier in serializerModifiers) { serializerModifier.SerializeMember(context, member); } if (ShouldSerializeUsingParseAndToString(member, true)) { var objectToStringValue = SerializeUsingObjectToString(context, member); if (!string.IsNullOrWhiteSpace(objectToStringValue)) { member.Value = objectToStringValue; } } SerializeMember(context, member); AfterSerializeMember(context, member); SerializedMember.SafeInvoke(this, memberSerializationEventArgs); } } }
public void ReturnsRightModifiersInRightOrderForInheritedClasses() { var serializationManager = new SerializationManager(); var modifiers = serializationManager.GetSerializerModifiers(typeof(TestModels.ModelC)); Assert.AreEqual(3, modifiers.Length); Assert.AreEqual(typeof(TestModels.ModelASerializerModifier), modifiers[0].GetType()); Assert.AreEqual(typeof(TestModels.ModelBSerializerModifier), modifiers[1].GetType()); Assert.AreEqual(typeof(TestModels.ModelCSerializerModifier), modifiers[2].GetType()); }
/// <summary> /// Returns whether the member value should be serialized as collection. /// </summary> /// <param name="memberType">Type of the member.</param> /// <returns><c>true</c> if the member value should be serialized as collection, <c>false</c> otherwise.</returns> protected virtual bool ShouldSerializeAsCollection(Type memberType) { return(_shouldSerializeAsCollectionCache.GetFromCacheOrFetch(memberType, () => { var serializerModifiers = SerializationManager.GetSerializerModifiers(memberType); if (serializerModifiers != null) { foreach (var serializerModifier in serializerModifiers) { var shouldSerializeAsCollection = serializerModifier.ShouldSerializeAsCollection(); if (shouldSerializeAsCollection.HasValue) { return shouldSerializeAsCollection.Value; } } } if (memberType == typeof(byte[])) { return false; } // An exception is ModelBase, we will always serialize ourselves (even when it is a collection) if (memberType.IsModelBase()) { return ShouldSerializeModelAsCollection(memberType); } if (memberType.IsCollection()) { return true; } if (memberType == typeof(IEnumerable)) { return true; } if (memberType.IsGenericTypeEx()) { var genericDefinition = memberType.GetGenericTypeDefinitionEx(); if (genericDefinition == typeof(IEnumerable <>) || typeof(IEnumerable <>).IsAssignableFromEx(genericDefinition)) { return true; } } return false; })); }
/// <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 specified model. /// </summary> /// <param name="model">The model.</param> /// <param name="serializationContext">The serialization context.</param> public virtual void Deserialize(ModelBase model, TSerializationContext serializationContext) { Argument.IsNotNull("model", model); Argument.IsNotNull("context", serializationContext); using (var finalContext = GetContext(model, serializationContext, SerializationContextMode.Deserialization)) { bool?previousLeanAndMeanValue = null; if (!ModelBase.GlobalLeanAndMeanModel) { previousLeanAndMeanValue = model.LeanAndMeanModel; model.LeanAndMeanModel = true; } var serializerModifiers = SerializationManager.GetSerializerModifiers(finalContext.ModelType); Log.Debug("Using '{0}' serializer modifiers to deserialize type '{1}'", serializerModifiers.Length, finalContext.ModelType.GetSafeFullName()); var serializingEventArgs = new SerializationEventArgs(finalContext); Deserializing.SafeInvoke(this, serializingEventArgs); foreach (var serializerModifier in serializerModifiers) { serializerModifier.OnDeserializing(finalContext, model); } BeforeDeserialization(finalContext); DeserializeMembers(finalContext); AfterDeserialization(finalContext); foreach (var serializerModifier in serializerModifiers) { serializerModifier.OnDeserialized(finalContext, model); } Deserialized.SafeInvoke(this, serializingEventArgs); model.FinishDeserialization(); if (previousLeanAndMeanValue.HasValue) { model.LeanAndMeanModel = previousLeanAndMeanValue.Value; } } }
/// <summary> /// Serializes the members. /// </summary> /// <param name="context">The context.</param> /// <param name="membersToSerialize">The members to serialize.</param> protected virtual void SerializeMembers(ISerializationContext <TSerializationContext> context, List <MemberValue> membersToSerialize) { ApiCop.UpdateRule <InitializationApiCopRule>("SerializerBase.WarmupAtStartup", x => x.SetInitializationMode(InitializationMode.Lazy, GetType().GetSafeFullName())); var scopeName = SerializationContextHelper.GetSerializationReferenceManagerScopeName(); using (ScopeManager <ISerializer> .GetScopeManager(scopeName, () => this)) { var serializerModifiers = SerializationManager.GetSerializerModifiers(context.ModelType); foreach (var member in membersToSerialize) { bool skipByModifiers = false; foreach (var serializerModifier in serializerModifiers) { if (serializerModifier.ShouldIgnoreMember(context, context.Model, member)) { skipByModifiers = true; break; } } if (skipByModifiers) { continue; } var memberSerializationEventArgs = new MemberSerializationEventArgs(context, member); SerializingMember.SafeInvoke(this, memberSerializationEventArgs); BeforeSerializeMember(context, member); foreach (var serializerModifier in serializerModifiers) { serializerModifier.SerializeMember(context, member); } SerializeMember(context, member); AfterSerializeMember(context, member); SerializedMember.SafeInvoke(this, memberSerializationEventArgs); } } }
/// <summary> /// Serializes the members. /// </summary> /// <param name="context">The context.</param> /// <param name="membersToSerialize">The members to serialize.</param> protected virtual void SerializeMembers(ISerializationContext <TSerializationContextInfo> context, List <MemberValue> membersToSerialize) { if (membersToSerialize.Count == 0) { return; } using (GetCurrentSerializationScopeManager(context.Configuration)) { var serializerModifiers = SerializationManager.GetSerializerModifiers(context.ModelType); foreach (var member in membersToSerialize) { if (StartMemberSerialization(context, member, serializerModifiers)) { EndMemberSerialization(context, member); } } } }
/// <summary> /// Returns whether the enum member value should be serialized as string. /// </summary> /// <param name="memberValue"></param> /// <param name="checkActualMemberType"></param> /// <returns></returns> protected virtual bool ShouldSerializeEnumAsString(MemberValue memberValue, bool checkActualMemberType) { var cacheKey = $"{memberValue.ModelTypeName}|{memberValue.Name}|{checkActualMemberType}"; return(_shouldSerializeEnumAsStringCache.GetFromCacheOrFetch(cacheKey, () => { var serializerModifiers = SerializationManager.GetSerializerModifiers(memberValue.ModelType); var fieldInfo = memberValue.ModelType.GetFieldEx(memberValue.Name); if (fieldInfo != null) { if (fieldInfo.IsDecoratedWithAttribute <SerializeEnumAsStringAttribute>()) { return true; } } var propertyInfo = memberValue.ModelType.GetPropertyEx(memberValue.Name); if (propertyInfo != null) { if (propertyInfo.IsDecoratedWithAttribute <SerializeEnumAsStringAttribute>()) { return true; } } // Note: serializer modifiers can always win foreach (var serializerModifier in serializerModifiers) { var value = serializerModifier.ShouldSerializeEnumMemberUsingToString(memberValue); if (value.HasValue) { return value.Value; } } return false; })); }
/// <summary> /// Serializes the members. /// </summary> /// <param name="context">The context.</param> /// <param name="membersToSerialize">The members to serialize.</param> protected virtual void SerializeMembers(ISerializationContext <TSerializationContext> context, List <MemberValue> membersToSerialize) { var serializerModifiers = SerializationManager.GetSerializerModifiers(context.ModelType); foreach (var member in membersToSerialize) { bool skipByModifiers = false; foreach (var serializerModifier in serializerModifiers) { if (serializerModifier.ShouldIgnoreMember(context, context.Model, member)) { skipByModifiers = true; break; } } if (skipByModifiers) { continue; } var memberSerializationEventArgs = new MemberSerializationEventArgs(context, member); SerializingMember.SafeInvoke(this, memberSerializationEventArgs); BeforeSerializeMember(context, member); foreach (var serializerModifier in serializerModifiers) { serializerModifier.SerializeMember(context, member); } SerializeMember(context, member); AfterSerializeMember(context, member); SerializedMember.SafeInvoke(this, memberSerializationEventArgs); } }
/// <summary> /// Deserializes the specified model. /// </summary> /// <param name="model">The model.</param> /// <param name="context">The serialization context.</param> protected virtual object Deserialize(object model, ISerializationContext <TSerializationContextInfo> context) { Argument.IsNotNull("model", model); Argument.IsNotNull("context", context); var serializerModifiers = SerializationManager.GetSerializerModifiers(context.ModelType); Log.Debug("Using '{0}' serializer modifiers to deserialize type '{1}'", serializerModifiers.Length, context.ModelTypeName); var serializingEventArgs = new SerializationEventArgs(context); Deserializing?.Invoke(this, serializingEventArgs); foreach (var serializerModifier in serializerModifiers) { serializerModifier.OnDeserializing(context, model); } BeforeDeserialization(context); var deserializedMemberValues = DeserializeMembers(context); PopulateModel(context, deserializedMemberValues); // Always use the deserialized model (might be a value type) model = context.Model; AfterDeserialization(context); foreach (var serializerModifier in serializerModifiers) { serializerModifier.OnDeserialized(context, model); } Deserialized?.Invoke(this, serializingEventArgs); return(model); }
/// <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 <TSerializationContextInfo> context) { var deserializedMemberValues = new List <MemberValue>(); var serializerModifiers = SerializationManager.GetSerializerModifiers(context.ModelType).Reverse(); var membersToDeserialize = GetSerializableMembers(context, context.Model); foreach (var member in membersToDeserialize) { StartMemberDeserialization(context, member); var serializationObject = DeserializeMember(context, member); var finalMemberValue = EndMemberDeserialization(context, member, serializationObject, serializerModifiers); if (finalMemberValue != null) { deserializedMemberValues.Add(finalMemberValue); } } return(deserializedMemberValues); }
public void RemovesSerializerModifier() { var serializationManager = new SerializationManager(); serializationManager.AddSerializerModifier<DynamicSerializerModifierModel, DynamicSerializerModifier>(); var modifiers = serializationManager.GetSerializerModifiers(typeof(DynamicSerializerModifierModel)); Assert.AreEqual(1, modifiers.Length); Assert.AreEqual(typeof(DynamicSerializerModifier), modifiers[0].GetType()); serializationManager.RemoveSerializerModifier<DynamicSerializerModifierModel, DynamicSerializerModifier>(); modifiers = serializationManager.GetSerializerModifiers(typeof(DynamicSerializerModifierModel)); Assert.AreEqual(0, modifiers.Length); }
/// <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> /// Returns whether the member value should be serialized using <c>ToString(IFormatProvider)</c> and deserialized using <c>Parse(string, IFormatProvider)</c>. /// </summary> /// <param name="memberValue">The member value.</param> /// <param name="checkActualMemberType">if set to <c>true</c>, check the actual member type.</param> /// <returns> /// <c>true</c> if the member should be serialized using parse. /// </returns> protected virtual bool ShouldSerializeUsingParseAndToString(MemberValue memberValue, bool checkActualMemberType) { var cacheKey = $"{memberValue.ModelTypeName}|{memberValue.Name}|{checkActualMemberType}"; return(_shouldSerializeUsingParseCache.GetFromCacheOrFetch(cacheKey, () => { var serializerModifiers = SerializationManager.GetSerializerModifiers(memberValue.ModelType); var useParseAndToString = false; var fieldInfo = memberValue.ModelType.GetFieldEx(memberValue.Name); if (fieldInfo != null) { useParseAndToString = fieldInfo.IsDecoratedWithAttribute <SerializeUsingParseAndToStringAttribute>(); } if (!useParseAndToString) { var propertyInfo = memberValue.ModelType.GetPropertyEx(memberValue.Name); if (propertyInfo != null) { useParseAndToString = propertyInfo.IsDecoratedWithAttribute <SerializeUsingParseAndToStringAttribute>(); } } // Note: serializer modifiers can always win foreach (var serializerModifier in serializerModifiers) { var value = serializerModifier.ShouldSerializeMemberUsingParse(memberValue); if (value.HasValue) { if (!value.Value) { return false; } // At least 1 serializer modifier wants this to be using parse and tostring useParseAndToString = true; } } if (!useParseAndToString) { return false; } var memberType = checkActualMemberType ? memberValue.ActualMemberType : memberValue.MemberType; if (memberType == null) { memberType = memberValue.MemberType; } var toStringMethod = GetObjectToStringMethod(memberType); if (toStringMethod == null) { return false; } var parseMethod = GetObjectParseMethod(memberType); if (parseMethod == null) { return false; } return true; })); }
public void ThrowsArgumentNullExceptionForNullType() { var serializationManager = new SerializationManager(); ExceptionTester.CallMethodAndExpectException<ArgumentNullException>(() => serializationManager.GetSerializerModifiers(null)); }