Skip to content

Commit b1ff672

Browse files
Merge 431c00e into 3940f0b
2 parents 3940f0b + 431c00e commit b1ff672

File tree

12 files changed

+249
-88
lines changed

12 files changed

+249
-88
lines changed

src/ExtendedXmlSerializer/ContentModel/Content/NullableContents.cs

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/ExtendedXmlSerializer/ContentModel/Members/MemberSerializers.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@ bool IsMember(IMember profile)
6060
IMemberSerializer Content(IMember profile, IMemberAccess access)
6161
{
6262
var identity = new Identity<object>(profile);
63-
var isMember = IsMember(profile);
64-
var composite = isMember
63+
var composite = IsMember(profile)
6564
? (IWriter<object>)new MemberPropertyWriter(identity)
6665
: identity;
6766
var start = composite.Adapt();

src/ExtendedXmlSerializer/ExtensionModel/Content/Contents.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ public IServiceRepository Get(IServiceRepository parameter)
4646
.DecorateContentsWith<ReflectionContents>()
4747
.When(ReflectionContentSpecification.Default)
4848

49-
.DecorateContentsWith<NullableContents>()
50-
.When(IsNullableTypeSpecification.Default)
51-
5249
.DecorateContentsWith<ConverterContents>()
5350
.When<ConverterSpecification>()
5451
.DecorateContentsWith<RegisteredContents>()

src/ExtendedXmlSerializer/ExtensionModel/Content/Members/ParameterizedResultHandler.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,9 @@ sealed class ParameterizedResultHandler : IInnerContentResult
77
{
88
readonly IInnerContentResult _result;
99

10-
public ParameterizedResultHandler(IInnerContentResult result)
11-
{
12-
_result = result;
13-
}
10+
public ParameterizedResultHandler(IInnerContentResult result) => _result = result;
1411

1512
public object Get(IInnerContent parameter)
16-
=> (parameter.Current as IActivationContext)?.Get() ?? _result.Get(parameter);
13+
=> parameter.Current is IActivationContext context ? context.Get() : _result.Get(parameter);
1714
}
1815
}

src/ExtendedXmlSerializer/ExtensionModel/DefaultExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public override IEnumerator<ISerializerExtension> GetEnumerator()
6060
yield return new MemberFormatExtension();
6161
yield return ImmutableArrayExtension.Default;
6262
yield return SerializationExtension.Default;
63+
yield return NullableStructureAwareExtension.Default;
6364
yield return new CustomSerializationExtension();
6465
yield return CachingExtension.Default;
6566
}

src/ExtendedXmlSerializer/ExtensionModel/SerializationExtension.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ public IServiceRepository Get(IServiceRepository parameter)
3232
.Register<RuntimeSerializers>()
3333
.Register<ISerializers, Serializers>()
3434
.RegisterInstance(RuntimeSerializationExceptionMessage.Default)
35-
.Decorate<ISerializers, NullableAwareSerializers>()
3635
.Decorate<ISerializers, ReferenceAwareSerializers>()
3736
.Decorate<ISerializers, DynamicAwareSerializers>()
3837
.Decorate<IContents, RecursionAwareContents>();
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using ExtendedXmlSerializer.ContentModel;
2+
using ExtendedXmlSerializer.ContentModel.Content;
3+
using System;
4+
using System.Reflection;
5+
6+
namespace ExtendedXmlSerializer.ExtensionModel.Types
7+
{
8+
sealed class NullableStructureAwareExtension : ISerializerExtension
9+
{
10+
public static NullableStructureAwareExtension Default { get; } = new NullableStructureAwareExtension();
11+
12+
NullableStructureAwareExtension() {}
13+
14+
public IServiceRepository Get(IServiceRepository parameter)
15+
=> parameter.DecorateContentsWith<NullableStructureAwareContents>().Then();
16+
17+
public void Execute(IServices parameter) {}
18+
19+
sealed class NullableStructureAwareContents : IContents
20+
{
21+
readonly IContents _previous;
22+
23+
public NullableStructureAwareContents(IContents previous) => _previous = previous;
24+
25+
public ISerializer Get(TypeInfo parameter)
26+
{
27+
var underlying = Nullable.GetUnderlyingType(parameter);
28+
var serializer = _previous.Get(underlying != null ? underlying : parameter);
29+
return serializer;
30+
}
31+
}
32+
}
33+
}

src/ExtendedXmlSerializer/ExtensionModel/Xml/AutoMemberFormatExtension.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
using System.Reflection;
21
using ExtendedXmlSerializer.ContentModel.Conversion;
32
using ExtendedXmlSerializer.ContentModel.Members;
43
using ExtendedXmlSerializer.Core;
54
using ExtendedXmlSerializer.Core.Specifications;
5+
using System.Reflection;
66

77
namespace ExtendedXmlSerializer.ExtensionModel.Xml
88
{
@@ -48,11 +48,7 @@ public MemberConverters(IMemberConverters members, IConverters converters)
4848
_converters = converters;
4949
}
5050

51-
public IConverter Get(MemberInfo parameter)
52-
{
53-
var converter = _members.Get(parameter);
54-
return converter ?? From(parameter);
55-
}
51+
public IConverter Get(MemberInfo parameter) => _members.Get(parameter) ?? From(parameter);
5652

5753
IConverter From(MemberDescriptor parameter) => _converters.Get(parameter.MemberType.AccountForNullable());
5854
}

src/ExtendedXmlSerializer/ReflectionModel/IsNullableTypeSpecification.cs

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
using ExtendedXmlSerializer.Configuration;
2+
using ExtendedXmlSerializer.Tests.ReportedIssues.Support;
3+
using FluentAssertions;
4+
using System;
5+
using Xunit;
6+
7+
#nullable enable
8+
namespace ExtendedXmlSerializer.Tests.ReportedIssues
9+
{
10+
public sealed class Issue477Tests
11+
{
12+
[Fact]
13+
public void SerializeAndDeserializeInstanceA()
14+
{
15+
var serializer = new ConfigurationContainer().EnableParameterizedContentWithPropertyAssignments()
16+
.Create()
17+
.ForTesting();
18+
19+
var instance = new A { Point = new Point(2, 3) };
20+
21+
serializer.Cycle(instance).Should().BeEquivalentTo(instance);
22+
}
23+
24+
[Fact]
25+
public void SerializeAndDeserializeInstanceB()
26+
{
27+
var serializer = new ConfigurationContainer().EnableParameterizedContent()
28+
.Create()
29+
.ForTesting();
30+
31+
var instance = new B { NullablePoint = new Point(24, 7) };
32+
33+
serializer.Cycle(instance).Should().BeEquivalentTo(instance);
34+
}
35+
36+
[Fact]
37+
public void SerializeAndDeserializeInstanceBNull()
38+
{
39+
var serializer = new ConfigurationContainer().EnableParameterizedContent()
40+
.Create()
41+
.ForTesting();
42+
43+
var instance = new B { NullablePoint = null };
44+
45+
serializer.Assert(instance, @"<?xml version=""1.0"" encoding=""utf-8""?><Issue477Tests-B xmlns=""clr-namespace:ExtendedXmlSerializer.Tests.ReportedIssues;assembly=ExtendedXmlSerializer.Tests.ReportedIssues"" />");
46+
47+
serializer.Cycle(instance).Should().BeEquivalentTo(instance);
48+
}
49+
50+
public sealed class A
51+
{
52+
public Point Point { get; set; }
53+
}
54+
55+
public sealed class B
56+
{
57+
public Point? NullablePoint { get; set; }
58+
}
59+
60+
public readonly struct Point : IEquatable<Point>
61+
{
62+
public Point(int x, int y)
63+
{
64+
X = x;
65+
Y = y;
66+
}
67+
68+
public int X { get; }
69+
70+
public int Y { get; }
71+
72+
public bool Equals(Point other) => X == other.X && Y == other.Y;
73+
74+
public override bool Equals(object? obj) => obj is Point other && Equals(other);
75+
76+
public override int GetHashCode()
77+
{
78+
unchecked
79+
{
80+
return (X * 397) ^ Y;
81+
}
82+
}
83+
84+
public override string ToString() => $"({X}, {Y})";
85+
86+
public static bool operator ==(Point left, Point right) => left.Equals(right);
87+
88+
public static bool operator !=(Point left, Point right) => !left.Equals(right);
89+
}
90+
}
91+
}
92+
#nullable restore
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using ExtendedXmlSerializer.Configuration;
2+
using ExtendedXmlSerializer.Tests.ReportedIssues.Support;
3+
using FluentAssertions;
4+
using System;
5+
using Xunit;
6+
7+
namespace ExtendedXmlSerializer.Tests.ReportedIssues
8+
{
9+
public sealed class Issue477Tests_Extended
10+
{
11+
[Fact]
12+
public void Verify()
13+
{
14+
var serializer = new ConfigurationContainer().Type<DateTime>()
15+
.Register()
16+
.Serializer()
17+
.ByCalling((writer, date) => writer.Content(date.ToString("yyyy-MM-dd")),
18+
null)
19+
.Type<DateTime?>()
20+
.Register()
21+
.Serializer()
22+
.ByCalling((writer, date) => writer.Content(date?.ToString("yyyy-MM-dd") ?? string.Empty), null)
23+
.Create()
24+
.ForTesting();
25+
26+
var instance = new Test();
27+
var content = serializer.Serialize(instance);
28+
29+
content.Should().Be(@"<?xml version=""1.0"" encoding=""utf-8""?><Issue477Tests_Extended-Test xmlns=""clr-namespace:ExtendedXmlSerializer.Tests.ReportedIssues;assembly=ExtendedXmlSerializer.Tests.ReportedIssues""><Date1>2020-11-23</Date1><Date3>2020-11-23</Date3></Issue477Tests_Extended-Test>");
30+
31+
32+
}
33+
34+
class Test
35+
{
36+
public DateTime Date1 { get; set; } = DateTime.Now; // Formatted OK
37+
public DateTime? Date2 { get; set; } = null; // Is not emitted = OK
38+
public DateTime? Date3 { get; set; } = DateTime.Now; // Completety ignores configured formatting
39+
}
40+
}
41+
}

0 commit comments

Comments
 (0)