diff --git a/YamlDotNet.Test/Serialization/SerializationTestHelper.cs b/YamlDotNet.Test/Serialization/SerializationTestHelper.cs index 50500bb3e..4b1023d04 100644 --- a/YamlDotNet.Test/Serialization/SerializationTestHelper.cs +++ b/YamlDotNet.Test/Serialization/SerializationTestHelper.cs @@ -378,7 +378,11 @@ public Example() public class IgnoreExample { [YamlIgnore] - public String IgnoreMe { get; set; } + public String IgnoreMe + { + get { throw new NotImplementedException("Accessing a [YamlIgnore] property"); } + set { throw new NotImplementedException("Accessing a [YamlIgnore] property"); } + } } public class DefaultsExample diff --git a/YamlDotNet.Test/Serialization/SerializationTests.cs b/YamlDotNet.Test/Serialization/SerializationTests.cs index 99978b12f..4f9eb1bf1 100644 --- a/YamlDotNet.Test/Serialization/SerializationTests.cs +++ b/YamlDotNet.Test/Serialization/SerializationTests.cs @@ -564,7 +564,7 @@ public void DeserializationOfDefaultsWorkInJson() public void SerializationRespectsYamlIgnoreAttribute() { var writer = new StringWriter(); - var obj = new IgnoreExample { IgnoreMe = "Some Text" }; + var obj = new IgnoreExample(); Serializer.Serialize(writer, obj); var serialized = writer.ToString(); diff --git a/YamlDotNet.build b/YamlDotNet.build index e5b27221e..510b8238f 100644 --- a/YamlDotNet.build +++ b/YamlDotNet.build @@ -4,7 +4,7 @@ - + diff --git a/YamlDotNet/Serialization/IObjectGraphVisitor.cs b/YamlDotNet/Serialization/IObjectGraphVisitor.cs index dccac7b7b..79f15cc58 100644 --- a/YamlDotNet/Serialization/IObjectGraphVisitor.cs +++ b/YamlDotNet/Serialization/IObjectGraphVisitor.cs @@ -53,7 +53,7 @@ public interface IObjectGraphVisitor /// The that provided access to . /// The value of the mapping that is about to be entered. /// If the mapping is to be entered, returns true; otherwise returns false; - bool EnterMapping(IPropertyDescriptor key, object value); + bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value); /// /// Notifies the visitor that a scalar value has been encountered. diff --git a/YamlDotNet/Serialization/IPropertyDescriptor.cs b/YamlDotNet/Serialization/IPropertyDescriptor.cs index ca3794b95..aa3c2a21a 100644 --- a/YamlDotNet/Serialization/IPropertyDescriptor.cs +++ b/YamlDotNet/Serialization/IPropertyDescriptor.cs @@ -23,13 +23,16 @@ namespace YamlDotNet.Serialization { - public interface IPropertyDescriptor : IObjectDescriptor + public interface IPropertyDescriptor { string Name { get; } bool CanWrite { get; } - - void SetValue(object target, object value); + Type Type { get; } + Type TypeOverride { get; set; } T GetCustomAttribute() where T : Attribute; + + IObjectDescriptor Read(object target); + void Write(object target, object value); } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/NodeDeserializers/ObjectNodeDeserializer.cs b/YamlDotNet/Serialization/NodeDeserializers/ObjectNodeDeserializer.cs index b5c3b504f..3c92f36ba 100644 --- a/YamlDotNet/Serialization/NodeDeserializers/ObjectNodeDeserializer.cs +++ b/YamlDotNet/Serialization/NodeDeserializers/ObjectNodeDeserializer.cs @@ -67,7 +67,7 @@ bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func { var convertedValue = TypeConverter.ChangeType(v, property.Type); - property.SetValue(valueRef, convertedValue); + property.Write(valueRef, convertedValue); }; } } diff --git a/YamlDotNet/Serialization/ObjectGraphTraversalStrategies/FullObjectGraphTraversalStrategy.cs b/YamlDotNet/Serialization/ObjectGraphTraversalStrategies/FullObjectGraphTraversalStrategy.cs index b581dc7c8..2571d0f4e 100644 --- a/YamlDotNet/Serialization/ObjectGraphTraversalStrategies/FullObjectGraphTraversalStrategy.cs +++ b/YamlDotNet/Serialization/ObjectGraphTraversalStrategies/FullObjectGraphTraversalStrategy.cs @@ -228,12 +228,12 @@ protected virtual void TraverseProperties(IObjectDescriptor value, IObjectGraphV foreach (var propertyDescriptor in typeDescriptor.GetProperties(value.Type, value.Value)) { - var propertyValue = propertyDescriptor.Value; + var propertyValue = propertyDescriptor.Read(value.Value); if (visitor.EnterMapping(propertyDescriptor, propertyValue)) { Traverse(new ObjectDescriptor(propertyDescriptor.Name, typeof(string), typeof(string)), visitor, currentDepth); - Traverse(propertyDescriptor, visitor, currentDepth); + Traverse(propertyValue, visitor, currentDepth); } } diff --git a/YamlDotNet/Serialization/ObjectGraphVisitors/AnchorAssigner.cs b/YamlDotNet/Serialization/ObjectGraphVisitors/AnchorAssigner.cs index fffd503b9..746037193 100644 --- a/YamlDotNet/Serialization/ObjectGraphVisitors/AnchorAssigner.cs +++ b/YamlDotNet/Serialization/ObjectGraphVisitors/AnchorAssigner.cs @@ -65,7 +65,7 @@ bool IObjectGraphVisitor.EnterMapping(IObjectDescriptor key, IObjectDescriptor v return true; } - bool IObjectGraphVisitor.EnterMapping(IPropertyDescriptor key, object value) + bool IObjectGraphVisitor.EnterMapping(IPropertyDescriptor key, IObjectDescriptor value) { return true; } diff --git a/YamlDotNet/Serialization/ObjectGraphVisitors/ChainedObjectGraphVisitor.cs b/YamlDotNet/Serialization/ObjectGraphVisitors/ChainedObjectGraphVisitor.cs index f24535b42..8aa910e94 100644 --- a/YamlDotNet/Serialization/ObjectGraphVisitors/ChainedObjectGraphVisitor.cs +++ b/YamlDotNet/Serialization/ObjectGraphVisitors/ChainedObjectGraphVisitor.cs @@ -42,7 +42,7 @@ public virtual bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value) return nextVisitor.EnterMapping(key, value); } - public virtual bool EnterMapping(IPropertyDescriptor key, object value) + public virtual bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value) { return nextVisitor.EnterMapping(key, value); } diff --git a/YamlDotNet/Serialization/ObjectGraphVisitors/DefaultExclusiveObjectGraphVisitor.cs b/YamlDotNet/Serialization/ObjectGraphVisitors/DefaultExclusiveObjectGraphVisitor.cs index 8218e76bb..9ddf78f6d 100644 --- a/YamlDotNet/Serialization/ObjectGraphVisitors/DefaultExclusiveObjectGraphVisitor.cs +++ b/YamlDotNet/Serialization/ObjectGraphVisitors/DefaultExclusiveObjectGraphVisitor.cs @@ -45,14 +45,14 @@ public override bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value && base.EnterMapping(key, value); } - public override bool EnterMapping(IPropertyDescriptor key, object value) + public override bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value) { var defaultValueAttribute = key.GetCustomAttribute(); var defaultValue = defaultValueAttribute != null ? defaultValueAttribute.Value : GetDefault(key.Type); - return !_objectComparer.Equals(value, defaultValue) + return !_objectComparer.Equals(value.Value, defaultValue) && base.EnterMapping(key, value); } } diff --git a/YamlDotNet/Serialization/ObjectGraphVisitors/EmittingObjectGraphVisitor.cs b/YamlDotNet/Serialization/ObjectGraphVisitors/EmittingObjectGraphVisitor.cs index 8e625bef8..45c336d1d 100644 --- a/YamlDotNet/Serialization/ObjectGraphVisitors/EmittingObjectGraphVisitor.cs +++ b/YamlDotNet/Serialization/ObjectGraphVisitors/EmittingObjectGraphVisitor.cs @@ -42,7 +42,7 @@ bool IObjectGraphVisitor.EnterMapping(IObjectDescriptor key, IObjectDescriptor v return true; } - bool IObjectGraphVisitor.EnterMapping(IPropertyDescriptor key, object value) + bool IObjectGraphVisitor.EnterMapping(IPropertyDescriptor key, IObjectDescriptor value) { return true; } diff --git a/YamlDotNet/Serialization/PropertyDescriptor.cs b/YamlDotNet/Serialization/PropertyDescriptor.cs index 264ef876d..e7562dd18 100644 --- a/YamlDotNet/Serialization/PropertyDescriptor.cs +++ b/YamlDotNet/Serialization/PropertyDescriptor.cs @@ -31,17 +31,16 @@ public PropertyDescriptor(IPropertyDescriptor baseDescriptor) { this.baseDescriptor = baseDescriptor; Name = baseDescriptor.Name; - Type = baseDescriptor.Type; - StaticType = baseDescriptor.StaticType; } public string Name { get; set; } - public Type Type { get; set; } - public Type StaticType { get; set; } - public object Value + public Type Type { get { return baseDescriptor.Type; } } + + public Type TypeOverride { - get { return baseDescriptor.Value; } + get { return baseDescriptor.TypeOverride; } + set { baseDescriptor.TypeOverride = value; } } public bool CanWrite @@ -49,14 +48,19 @@ public bool CanWrite get { return baseDescriptor.CanWrite; } } - public void SetValue(object target, object value) + public void Write(object target, object value) { - baseDescriptor.SetValue(target, value); + baseDescriptor.Write(target, value); } public T GetCustomAttribute() where T : Attribute { return baseDescriptor.GetCustomAttribute(); } + + public IObjectDescriptor Read(object target) + { + return baseDescriptor.Read(target); + } } } diff --git a/YamlDotNet/Serialization/TypeInspectors/ReadablePropertiesTypeInspector.cs b/YamlDotNet/Serialization/TypeInspectors/ReadablePropertiesTypeInspector.cs index b8d699236..f23e7d896 100644 --- a/YamlDotNet/Serialization/TypeInspectors/ReadablePropertiesTypeInspector.cs +++ b/YamlDotNet/Serialization/TypeInspectors/ReadablePropertiesTypeInspector.cs @@ -31,16 +31,16 @@ namespace YamlDotNet.Serialization.TypeInspectors /// public sealed class ReadablePropertiesTypeInspector : TypeInspectorSkeleton { - private readonly ITypeResolver _reflectionPropertyDescriptorFactory; + private readonly ITypeResolver _typeResolver; - public ReadablePropertiesTypeInspector(ITypeResolver reflectionPropertyDescriptorFactory) + public ReadablePropertiesTypeInspector(ITypeResolver typeResolver) { - if (reflectionPropertyDescriptorFactory == null) + if (typeResolver == null) { - throw new ArgumentNullException("reflectionPropertyDescriptorFactory"); + throw new ArgumentNullException("typeResolver"); } - _reflectionPropertyDescriptorFactory = reflectionPropertyDescriptorFactory; + _typeResolver = typeResolver; } private static bool IsValidProperty(PropertyInfo property) @@ -54,34 +54,26 @@ public override IEnumerable GetProperties(Type type, object return type .GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(IsValidProperty) - .Select(p => - { - var propertyValue = container != null - ? p.GetValue(container, null) - : null; - - return (IPropertyDescriptor)new ReflectionPropertyDescriptor(p, _reflectionPropertyDescriptorFactory.Resolve(p.PropertyType, propertyValue), propertyValue); - }); + .Select(p => (IPropertyDescriptor)new ReflectionPropertyDescriptor(p, _typeResolver)); } private sealed class ReflectionPropertyDescriptor : IPropertyDescriptor { private readonly PropertyInfo _propertyInfo; + private readonly ITypeResolver _typeResolver; - public ReflectionPropertyDescriptor(PropertyInfo propertyInfo, Type type, object value) + public ReflectionPropertyDescriptor(PropertyInfo propertyInfo, ITypeResolver typeResolver) { _propertyInfo = propertyInfo; - Type = type; - Value = value; + _typeResolver = typeResolver; } public string Name { get { return _propertyInfo.Name; } } - public Type Type { get; private set; } - public Type StaticType { get { return _propertyInfo.PropertyType; } } - public object Value { get; private set; } + public Type Type { get { return _propertyInfo.PropertyType; } } + public Type TypeOverride { get; set; } public bool CanWrite { get { return _propertyInfo.CanWrite; } } - public void SetValue(object target, object value) + public void Write(object target, object value) { _propertyInfo.SetValue(target, value, null); } @@ -93,6 +85,13 @@ public void SetValue(object target, object value) ? (T)attributes[0] : null; } + + public IObjectDescriptor Read(object target) + { + var propertyValue = _propertyInfo.GetValue(target, null); + var actualType = TypeOverride ?? _typeResolver.Resolve(Type, propertyValue); + return new ObjectDescriptor(propertyValue, actualType, Type); + } } } } diff --git a/YamlDotNet/Serialization/YamlAttributesTypeInspector.cs b/YamlDotNet/Serialization/YamlAttributesTypeInspector.cs index febeef26a..f42b36802 100644 --- a/YamlDotNet/Serialization/YamlAttributesTypeInspector.cs +++ b/YamlDotNet/Serialization/YamlAttributesTypeInspector.cs @@ -57,7 +57,7 @@ public override IEnumerable GetProperties(Type type, object { if (member.SerializeAs != null) { - descriptor.Type = member.SerializeAs; + descriptor.TypeOverride = member.SerializeAs; } }