Skip to content

Commit

Permalink
Added support for IReadOnlyList properties.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mike-E-angelo committed Jul 21, 2020
1 parent b8fb4d4 commit a1589f5
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 4 deletions.
13 changes: 11 additions & 2 deletions src/ExtendedXmlSerializer/ReflectionModel/DefaultActivators.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using ExtendedXmlSerializer.Core.Sources;
using ExtendedXmlSerializer.Core.Specifications;
using System;
using System.Collections.Generic;
using System.Linq;
Expand Down Expand Up @@ -35,10 +36,10 @@ protected override IActivator Create(Type parameter)

NewExpression Reference(Type parameter, TypeInfo typeInfo)
{
var accounted = typeInfo.IsInterface && IsCollectionTypeSpecification.Default.IsSatisfiedBy(parameter)
var accounted = typeInfo.IsInterface && IsCollectionType.Instance.IsSatisfiedBy(parameter)
? typeof(List<>).MakeGenericType(CollectionItemTypeLocator.Default.Get(typeInfo))
: typeInfo;
var constructor = _locator.Get(accounted);
var constructor = _locator.Get(accounted) ?? _locator.Get(typeInfo);
var parameters = constructor.GetParameters();
var result = parameters.Length > 0
? Expression.New(constructor, parameters.Select(Selector))
Expand All @@ -63,5 +64,13 @@ public Expression Get(ParameterInfo parameter)
Initializers)
: Expression.Default(parameter.ParameterType);
}

sealed class IsCollectionType : AnySpecification<TypeInfo>
{
public static IsCollectionType Instance { get; } = new IsCollectionType();

IsCollectionType() : base(IsCollectionTypeSpecification.Default,
new IsAssignableGenericSpecification(typeof(IReadOnlyCollection<>))) {}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sealed class IsCollectionTypeSpecification : AnySpecification<TypeInfo>
public static IsCollectionTypeSpecification Default { get; } = new IsCollectionTypeSpecification();

IsCollectionTypeSpecification()
: base(IsAssignableSpecification<IList>.Default, new IsAssignableGenericSpecification(typeof(ICollection<>))
) {}
: base(IsAssignableSpecification<IList>.Default,
new IsAssignableGenericSpecification(typeof(ICollection<>))) {}
}
}
73 changes: 73 additions & 0 deletions test/ExtendedXmlSerializer.Tests.ReportedIssues/Issue396Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using ExtendedXmlSerializer.Configuration;
using ExtendedXmlSerializer.Tests.ReportedIssues.Support;
using FluentAssertions;
using System;
using System.Collections.Generic;
using Xunit;

namespace ExtendedXmlSerializer.Tests.ReportedIssues
{
public sealed class Issue396Tests
{
[Fact]
public void NodesListIsMissingNodes()
{
var serializer = new ConfigurationContainer().UseOptimizedNamespaces()
.EnableParameterizedContentWithPropertyAssignments()
.UseAutoFormatting()
.Type<Node>()
.EnableReferences()
.Create()
.ForTesting();
var node1 = new Node(1);
var node2 = new Node(2).AddNode(node1, isBidirectional: true);
var node3 = new Node(3).AddNode(node2, isBidirectional: false);
node1.AddNode(node3, isBidirectional: false);
var nodesList = new List<Node> { node1, node2, node3 };



var cycled = serializer.Cycle(nodesList);
cycled.Should().BeEquivalentTo(nodesList, config => config.IgnoringCyclicReferences());
}

public sealed class Node : IEquatable<Node>
{
private readonly List<Node> _linkedNodes;

public Node(int id) : this(id, new List<Node>()) {}

public Node(int id, List<Node> linkedNodes)
{
Id = id;
_linkedNodes = linkedNodes ?? new List<Node>();
}

public int Id { get; }

public IReadOnlyList<Node> LinkedNodes => _linkedNodes;

// ReSharper disable once FlagArgument
public Node AddNode(Node otherNode, bool isBidirectional = true)
{
if (otherNode == null)
throw new ArgumentNullException(nameof(otherNode));
if (ReferenceEquals(this, otherNode))
throw new ArgumentException($"You cannot link a node {Id} to itself.");

_linkedNodes.Add(otherNode);
if (isBidirectional)
otherNode.AddNode(this, false);
return this;
}

public bool Equals(Node other) => !ReferenceEquals(null, other) && Id == other.Id;

public override bool Equals(object obj) => ReferenceEquals(this, obj) || obj is Node other && Equals(other);

public override int GetHashCode() => Id;

public override string ToString() => "Node " + Id;
}
}
}

0 comments on commit a1589f5

Please sign in to comment.