Skip to content

Commit

Permalink
Updating reference object after deserialization/activation.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mike-E-angelo committed Jul 21, 2020
1 parent b51263c commit 7e2d9b4
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using ExtendedXmlSerializer.ContentModel;
using ExtendedXmlSerializer.ContentModel.Content;
using ExtendedXmlSerializer.ContentModel.Format;
using ExtendedXmlSerializer.ContentModel.Properties;
using ExtendedXmlSerializer.ContentModel.Reflection;
using System.Reflection;
using System.Xml;
Expand Down Expand Up @@ -29,7 +30,8 @@ public ReferenceReader(IReader reader, IReferenceMaps maps, IEntities entities,

ReferenceIdentity? GetReference(IFormatReader parameter)
{
if (parameter.Get().To<XmlReader>().NodeType != XmlNodeType.Attribute || MemberProperty.Default.Get(parameter))
if (parameter.Get().To<XmlReader>().NodeType != XmlNodeType.Attribute ||
MemberProperty.Default.Get(parameter))
{
var identity = ReferenceIdentity.Get(parameter);
if (identity.HasValue)
Expand All @@ -50,17 +52,49 @@ public ReferenceReader(IReader reader, IReferenceMaps maps, IEntities entities,

public override object Get(IFormatReader parameter)
{
var identity = GetReference(parameter);
if (identity != null)
var reference = GetReference(parameter);
if (reference != null)
{
var result = _maps.Get(parameter).Get(identity.Value);
var result = _maps.Get(parameter).Get(reference.Value);
return result;
}

{
var result = base.Get(parameter);
var element = parameter.Get().To<XmlReader>().NodeType != XmlNodeType.Attribute ||
MemberProperty.Default.Get(parameter);
var declared = element ? Identity(parameter) : null;
var result = base.Get(parameter);
var identity = declared ?? (element && result != null ? Entity(parameter, result) : null);
if (identity != null)
{
var map = _maps.Get(parameter);
if (map.Get(identity.Value) != result)
{
map.Assign(identity.Value, result);
}
}

return result;
}
}

static ReferenceIdentity? Identity(IFormatReader reader)
{
var identity = IdentityProperty.Default.Get(reader);
var result = identity.HasValue ? new ReferenceIdentity(identity.Value) : (ReferenceIdentity?)null;
return result;
}

ReferenceIdentity? Entity(IFormatReader reader, object instance)
{
var typeInfo = instance.GetType()
.GetTypeInfo();
var entity = _entities.Get(typeInfo)
?.Get(reader);
var result = entity != null
? (ReferenceIdentity?)new ReferenceIdentity(typeInfo, entity)
: null;
return result;
}
}
}
60 changes: 60 additions & 0 deletions test/ExtendedXmlSerializer.Tests.ReportedIssues/Issue418Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using ExtendedXmlSerializer.Configuration;
using ExtendedXmlSerializer.Tests.ReportedIssues.Support;
using FluentAssertions;
using System.Collections.Generic;
using System.Linq;
using Xunit;

namespace ExtendedXmlSerializer.Tests.ReportedIssues
{
public sealed class Issue418Tests
{
[Fact]
public void Verify()
{
var b1 = new Book();
var b2 = new Book();

var allBooks = new[] {b1, b2,};

var fs = new BookStore()
{
AllBooks = allBooks,
Genres = new[]
{
new Genre
{
Books = allBooks,
},
new Genre
{
Books = allBooks,
},
}
};

var serializer = new ConfigurationContainer().Type<Book[]>()
.EnableReferences()
.Create()
.ForTesting();

var cycled = serializer.Cycle(fs);

cycled.AllBooks.Should().BeSameAs(cycled.Genres.ElementAt(0).Books);
cycled.AllBooks.Should().BeSameAs(cycled.Genres.ElementAt(1).Books);
}

class BookStore
{
public IEnumerable<Book> AllBooks { get; set; }
public IEnumerable<Genre> Genres { get; set; }
}

class Book {}

class Genre
{
public IEnumerable<Book> Books { get; set; }
}
}
}

0 comments on commit 7e2d9b4

Please sign in to comment.