diff --git a/src/ExtendedXmlSerializer/ExtensionModel/DefaultExtensions.cs b/src/ExtendedXmlSerializer/ExtensionModel/DefaultExtensions.cs index 94deaf682..964ee2451 100644 --- a/src/ExtendedXmlSerializer/ExtensionModel/DefaultExtensions.cs +++ b/src/ExtendedXmlSerializer/ExtensionModel/DefaultExtensions.cs @@ -59,6 +59,7 @@ public override IEnumerator GetEnumerator() yield return new AllowedMemberValuesExtension(); yield return new MemberFormatExtension(); yield return ImmutableArrayExtension.Default; + yield return ImmutableListExtension.Default; yield return SerializationExtension.Default; yield return NullableStructureAwareExtension.Default; yield return new CustomSerializationExtension(); diff --git a/src/ExtendedXmlSerializer/ExtensionModel/Types/ImmutableListExtension.cs b/src/ExtendedXmlSerializer/ExtensionModel/Types/ImmutableListExtension.cs new file mode 100644 index 000000000..4fd1be181 --- /dev/null +++ b/src/ExtendedXmlSerializer/ExtensionModel/Types/ImmutableListExtension.cs @@ -0,0 +1,94 @@ +using ExtendedXmlSerializer.ContentModel; +using ExtendedXmlSerializer.ContentModel.Collections; +using ExtendedXmlSerializer.ContentModel.Content; +using ExtendedXmlSerializer.ContentModel.Format; +using ExtendedXmlSerializer.ContentModel.Identification; +using ExtendedXmlSerializer.ContentModel.Reflection; +using ExtendedXmlSerializer.Core; +using ExtendedXmlSerializer.Core.Specifications; +using ExtendedXmlSerializer.ReflectionModel; +using JetBrains.Annotations; +using System.Collections.Immutable; +using System.Collections.ObjectModel; +using System.Reflection; + +namespace ExtendedXmlSerializer.ExtensionModel.Types +{ + sealed class ImmutableListExtension : ISerializerExtension + { + public static ImmutableListExtension Default { get; } = new ImmutableListExtension(); + + ImmutableListExtension() : this(new IsAssignableGenericSpecification(typeof(ImmutableList<>))) {} + + readonly ISpecification _specification; + + public ImmutableListExtension(ISpecification specification) => _specification = specification; + + public IServiceRepository Get(IServiceRepository parameter) + => parameter.DecorateContentsWith() + .When(_specification) + .Decorate(); + + void ICommand.Execute(IServices parameter) {} + + sealed class GenericTypes : IGenericTypes + { + readonly static TypeInfo Check = typeof(ImmutableList).GetTypeInfo(); + readonly static ImmutableArray Type = typeof(ImmutableList<>).GetTypeInfo() + .Yield() + .ToImmutableArray(); + + readonly IGenericTypes _types; + + public GenericTypes(IGenericTypes types) => _types = types; + + public ImmutableArray Get(IIdentity parameter) + { + var type = _types.Get(parameter); + var result = Equals(type.Only(), Check) ? Type : type; + return result; + } + } + + sealed class ImmutableLists : Collections + { + public ImmutableLists(RuntimeSerializers serializers, Contents contents) : base(serializers, contents) {} + } + + sealed class Contents : ICollectionContents + { + readonly IInnerContentServices _contents; + readonly IEnumerators _enumerators; + + public Contents(IInnerContentServices contents, IEnumerators enumerators) + { + _contents = contents; + _enumerators = enumerators; + } + + public ISerializer Get(CollectionContentInput parameter) + => new Serializer(Readers.Instance.Get(parameter.ItemType)(_contents, parameter.Item), + new EnumerableWriter(_enumerators, parameter.Item).Adapt()); + + sealed class Readers : Generic + { + public static Readers Instance { get; } = new Readers(); + + Readers() : base(typeof(Reader<>)) {} + } + + sealed class Reader : IReader + { + readonly IReader> _reader; + + [UsedImplicitly] + public Reader(IInnerContentServices services, IReader item) + : this(services.CreateContents>(new CollectionInnerContentHandler(item, services))) {} + + Reader(IReader> reader) => _reader = reader; + + public object Get(IFormatReader parameter) => _reader.Get(parameter).ToImmutableList(); + } + } + } +} \ No newline at end of file diff --git a/src/ExtendedXmlSerializer/ExtensionModel/Xml/MigrationsExtension.cs b/src/ExtendedXmlSerializer/ExtensionModel/Xml/MigrationsExtension.cs index 48bbdfc0e..0c9518305 100644 --- a/src/ExtendedXmlSerializer/ExtensionModel/Xml/MigrationsExtension.cs +++ b/src/ExtendedXmlSerializer/ExtensionModel/Xml/MigrationsExtension.cs @@ -19,13 +19,20 @@ namespace ExtendedXmlSerializer.ExtensionModel.Xml { - sealed class MigrationsExtension : TypedTable>>, ISerializerExtension + /// + /// This extension is meant for internal use, but has been exposed for extension authors who require access to it. + /// + /// + public sealed class MigrationsExtension : TypedTable>>, ISerializerExtension { + /// [UsedImplicitly] public MigrationsExtension() : this(new Dictionary>>()) {} + /// public MigrationsExtension(IDictionary>> store) : base(store) {} + /// public IServiceRepository Get(IServiceRepository parameter) => parameter.Decorate(Register); IContents Register(IServiceProvider services, IContents contents) diff --git a/test/ExtendedXmlSerializer.Tests.ReportedIssues/Issue483Tests.cs b/test/ExtendedXmlSerializer.Tests.ReportedIssues/Issue483Tests.cs new file mode 100644 index 000000000..bacc30e65 --- /dev/null +++ b/test/ExtendedXmlSerializer.Tests.ReportedIssues/Issue483Tests.cs @@ -0,0 +1,19 @@ +using ExtendedXmlSerializer.Configuration; +using ExtendedXmlSerializer.ExtensionModel.Xml; +using FluentAssertions; +using Xunit; + +namespace ExtendedXmlSerializer.Tests.ReportedIssues +{ + public sealed class Issue483Tests + { + [Fact] + public void Verify() + { + new ConfigurationContainer().Type().Root.With().Should().NotBeNull(); + + } + + + } +} diff --git a/test/ExtendedXmlSerializer.Tests.ReportedIssues/Issue485Tests.cs b/test/ExtendedXmlSerializer.Tests.ReportedIssues/Issue485Tests.cs new file mode 100644 index 000000000..b03764038 --- /dev/null +++ b/test/ExtendedXmlSerializer.Tests.ReportedIssues/Issue485Tests.cs @@ -0,0 +1,25 @@ +using ExtendedXmlSerializer.Configuration; +using ExtendedXmlSerializer.Tests.ReportedIssues.Support; +using FluentAssertions; +using System.Collections.Immutable; +using Xunit; + +namespace ExtendedXmlSerializer.Tests.ReportedIssues +{ + public sealed class Issue485Tests + { + [Fact] + public void Verify() + { + var instance = new[] { 1, 2, 3, 4 }.ToImmutableList(); + + var serializer = new ConfigurationContainer().UseAutoFormatting() + .UseOptimizedNamespaces() + .EnableParameterizedContentWithPropertyAssignments() + .Create() + .ForTesting(); + + serializer.Cycle(instance).Should().BeEquivalentTo(instance); + } + } +} \ No newline at end of file