Allow complex members to be updated rather than reset.

When deserializing into an existing object, it is usually the case that any complex members should be preserved. The current behaviour resets any existing members, and only sets the values included in the yaml file - any other properties are reset. The changes here ensure that existing members are preserved, and only properties included in the yaml are changed.

Two tests have been written to clarify the new behaviour.
This commit is contained in:
Peter Davidson 2015-03-25 02:18:06 +10:00 коммит произвёл Alexandre Mutel
Родитель cd222f16a3
Коммит d52feffe78
3 изменённых файлов: 53 добавлений и 8 удалений

Просмотреть файл

@ -747,6 +747,54 @@ Name: Andy
Assert.AreEqual(30, andy.Age);
}
public class Family {
public ExtendedPerson Mother { get; set; }
public ExtendedPerson Father { get; set; }
}
[Test]
public void DeserializeIntoExistingSubObjects() {
var serializer = new Serializer();
var andy = new ExtendedPerson { Name = "Not Andy", Age = 30 };
var amy = new ExtendedPerson { Name = "Amy", Age = 33 };
var family = new Family { Father = andy, Mother = amy };
var yaml = @"---
Mother:
Name: Betty
Age: 22
Father:
Name: Andy
...";
family = serializer.DeserializeInto<Family>(yaml, family);
Assert.AreEqual("Andy", family.Father.Name);
Assert.AreEqual("Betty", family.Mother.Name);
// Existing behaviour will pass with the commented line
//Assert.AreEqual(0, family.Father.Age);
Assert.AreEqual(30, family.Father.Age);
Assert.AreEqual(22, family.Mother.Age);
}
[Test]
public void DeserializeWithRepeatedSubObjects() {
var serializer = new Serializer();
var yaml = @"---
Mother:
Name: Betty
Mother:
Age: 22
...";
var family = serializer.Deserialize<Family>(yaml);
Assert.IsNull(family.Father);
// Note: This is the behaviour I would expect
// Existing behaviour will pass with the commented line
//Assert.IsNull(family.Mother.Name);
Assert.AreEqual("Betty", family.Mother.Name);
Assert.AreEqual(22, family.Mother.Age);
}
[Test]
public void DeserializeEmptyDocument()
{

Просмотреть файл

@ -106,6 +106,9 @@
<Name>SharpYaml</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

Просмотреть файл

@ -198,14 +198,8 @@ namespace SharpYaml.Serialization.Serializers
throw new YamlException(memberScalar.Start, memberScalar.End, "Unable to deserialize property [{0}] not found in type [{1}]".DoFormat(memberName, objectContext.Descriptor));
}
// Read the value according to the type
object memberValue = null;
if (memberAccessor.SerializeMemberMode == SerializeMemberMode.Content)
{
memberValue = memberAccessor.Get(objectContext.Instance);
}
// Read the previous value to allow reusing existing instance (e.g when members are created in the constructor of the object)
var memberValue = memberAccessor.Get(objectContext.Instance);
memberValue = ReadMemberValue(ref objectContext, memberAccessor, memberValue, memberAccessor.Type);
// Handle late binding