diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 95a29b12..568754ea 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,10 +1,22 @@ -### 0.9.17 March 25 2021 #### -* [Bump Microsoft.NET.Test.Sdk from 16.6.1 to 16.7.1](https://github.com/akkadotnet/Hyperion/pull/182) -* [Fix unit test problem](https://github.com/akkadotnet/Hyperion/pull/191) -* [Bump FSharp.Core from 4.7.2 to 5.0.0](https://github.com/akkadotnet/Hyperion/pull/189) -* [Fix issue #40 regarding partial streams](https://github.com/akkadotnet/Hyperion/pull/185) -* [Fix Hyperion not using known serializers when defined](https://github.com/akkadotnet/Hyperion/pull/184) -* [Bump Microsoft.NET.Test.Sdk from 16.7.1 to 16.8.3](https://github.com/akkadotnet/Hyperion/pull/196) -* [Bump System.Collections.Immutable from 1.7.1 to 5.0.0](https://github.com/akkadotnet/Hyperion/pull/195) -* [Bump FSharp.Core from 5.0.0 to 5.0.1](https://github.com/akkadotnet/Hyperion/pull/202) -* [Update the cross framework spec to include complex POCO object, Type serialization, and support for netcoreapp3.1 and net5.0](https://github.com/akkadotnet/Hyperion/pull/204) +### 0.10.0 April 13 2021 #### +* [Add a generic cross platform serialization support](https://github.com/akkadotnet/Hyperion/pull/208) + +# Cross platform serialization + +You can now address any cross platform package serialization differences by providing a list of package name transformation lambda function into the `SerializerOptions` constructor. The package name will be passed into the lambda function before it is deserialized, and the result of the string transformation is used for deserialization instead of the original package name. + +This short example shows how to address the change from `System.Drawing` in .NET Framework to `System.Drawing.Primitives` in .NET Core: + +``` +Serializer serializer; +#if NETFX +serializer = new Serializer(new SerializerOptions( + packageNameOverrides: new List> { + str => str.Contains("System.Drawing.Primitives") ? str.Replace(".Primitives", "") : str + })); +#elif NETCOREAPP +serializer = new Serializer(); +#endif +``` + +Note that only one package name transformation is allowed, any transform lambda function after the first applied transformation is ignored. \ No newline at end of file diff --git a/build-system/windows-release.yaml b/build-system/windows-release.yaml index 43fe3dfb..fa008f77 100644 --- a/build-system/windows-release.yaml +++ b/build-system/windows-release.yaml @@ -25,7 +25,7 @@ steps: displayName: 'FAKE Build' inputs: filename: build.cmd - arguments: 'All SignClientUser=$(signingUsername) SignClientSecret=$(signingPassword) nugetpublishurl=https://www.nuget.org/api/v2/package nugetkey=$(hyperionKey)' + arguments: 'nuget nugetpublishurl=https://www.nuget.org/api/v2/package nugetkey=$(hyperionKey)' - task: GitHubRelease@0 displayName: 'GitHub release (create)' @@ -35,4 +35,4 @@ steps: title: '$(projectName) v$(Build.SourceBranchName)' releaseNotesFile: 'RELEASE_NOTES.md' assets: | - bin\nuget\*.nupkg \ No newline at end of file + bin\nuget\*.nupkg diff --git a/src/Hyperion.Tests/Bugs.cs b/src/Hyperion.Tests/Bugs.cs index ebd9f562..4a4ed53f 100644 --- a/src/Hyperion.Tests/Bugs.cs +++ b/src/Hyperion.Tests/Bugs.cs @@ -11,6 +11,7 @@ using System.Collections; using System.Collections.Generic; using System.Collections.Immutable; +using System.Drawing; using System.IO; using System.Linq; using System.Reflection; @@ -24,7 +25,7 @@ namespace Hyperion.Tests { - public class Bugs + public class Bugs : TestBase { private readonly ITestOutputHelper _output; @@ -218,6 +219,19 @@ public void CanSerializeUri() Assert.Equal(stream.Length, stream.Position); } + #region Issue 117 + + [Fact] + public void CanSerializeColor() + { + var expected = Color.Aquamarine; + Serialize(expected); + Reset(); + var actual = Deserialize(); + Assert.Equal(expected, actual); + } + + #endregion public class SnapshotSelectionCriteria { diff --git a/src/Hyperion.Tests/CrossFrameworkSerializationTests.cs b/src/Hyperion.Tests/CrossFrameworkSerializationTests.cs index 32e9d203..e3bddbcf 100644 --- a/src/Hyperion.Tests/CrossFrameworkSerializationTests.cs +++ b/src/Hyperion.Tests/CrossFrameworkSerializationTests.cs @@ -1,7 +1,9 @@ -using System.Collections; +using System; +using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using FluentAssertions; using Hyperion.Tests.Generator; using Xunit; @@ -19,9 +21,21 @@ public class CrossFrameworkSerializationTests public CrossFrameworkSerializationTests(ITestOutputHelper log) { _log = log; - _serializer = new Serializer(); _originalObject = CrossFrameworkInitializer.Init(); _originalMixedObject = CrossFrameworkInitializer.InitMixed(); + + // Demonstrating the use of custom dll package name override + // to convert netcore System.Drawing.Primitives to netfx + // System.Drawing package. + #if NETFX + _serializer = new Serializer(new SerializerOptions( + packageNameOverrides: new List> + { + str => str.Contains("System.Drawing.Primitives") ? str.Replace(".Primitives", "") : str + })); + #elif NETCOREAPP + _serializer = new Serializer(); + #endif } public static IEnumerable SerializationFiles() diff --git a/src/Hyperion.Tests/Generator/CrossFrameworkClass.cs b/src/Hyperion.Tests/Generator/CrossFrameworkClass.cs index 17d3966b..7d19736c 100644 --- a/src/Hyperion.Tests/Generator/CrossFrameworkClass.cs +++ b/src/Hyperion.Tests/Generator/CrossFrameworkClass.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Drawing; namespace Hyperion.Tests.Generator { @@ -144,6 +146,15 @@ public class CrossFrameworkMixedClass : CrossFrameworkBase public Type FriendType { get; set; } public CrossFrameworkClass Data { get; set; } + // Test case for (netcore) System.Drawing.Primitives to (net45) System.Drawing + public Color Color { get; set; } + public Point Point { get; set; } + public PointF PointF { get; set; } + public Rectangle Rectangle { get; set; } + public RectangleF RectangleF { get; set; } + public Size Size { get; set; } + public SizeF SizeF { get; set; } + public override bool Equals(object obj) { if (!(obj is CrossFrameworkMixedClass other)) diff --git a/src/Hyperion.Tests/Generator/CrossFrameworkInitializer.cs b/src/Hyperion.Tests/Generator/CrossFrameworkInitializer.cs index b263e7c4..f7227ad5 100644 --- a/src/Hyperion.Tests/Generator/CrossFrameworkInitializer.cs +++ b/src/Hyperion.Tests/Generator/CrossFrameworkInitializer.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Drawing; namespace Hyperion.Tests.Generator { @@ -13,6 +15,13 @@ public static CrossFrameworkMixedClass InitMixed() Name = "Cookie", Sound = "Bark", FriendType = typeof(CrossFrameworkClass), + Color = Color.Blue, + Point = new Point(10, 10), + PointF = new PointF(10, 10), + Rectangle = new Rectangle(10, 10, 10, 10), + RectangleF = new RectangleF(10, 10, 10, 10), + Size = new Size(10, 10), + SizeF = new SizeF(10, 10), Data = Init() }; } diff --git a/src/Hyperion.Tests/Hyperion.Tests.csproj b/src/Hyperion.Tests/Hyperion.Tests.csproj index 3686b3a8..fb290e00 100644 --- a/src/Hyperion.Tests/Hyperion.Tests.csproj +++ b/src/Hyperion.Tests/Hyperion.Tests.csproj @@ -9,6 +9,14 @@ Hyperion.Tests.Generator.Program + + $(DefineConstants);NETCOREAPP + + + + $(DefineConstants);NETFX + + @@ -22,4 +30,9 @@ + + + true + + diff --git a/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv2.0.tf b/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv2.0.tf index 4cc8d17f..a2ef61f5 100644 Binary files a/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv2.0.tf and b/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv2.0.tf differ diff --git a/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv2.1.tf b/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv2.1.tf index 4cc8d17f..a2ef61f5 100644 Binary files a/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv2.1.tf and b/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv2.1.tf differ diff --git a/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv2.2.tf b/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv2.2.tf index 4cc8d17f..a2ef61f5 100644 Binary files a/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv2.2.tf and b/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv2.2.tf differ diff --git a/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv3.0.tf b/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv3.0.tf index 4cc8d17f..a2ef61f5 100644 Binary files a/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv3.0.tf and b/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv3.0.tf differ diff --git a/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv3.1.tf b/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv3.1.tf index 4cc8d17f..a2ef61f5 100644 Binary files a/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv3.1.tf and b/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv3.1.tf differ diff --git a/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv5.0.tf b/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv5.0.tf index 4cc8d17f..a2ef61f5 100644 Binary files a/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv5.0.tf and b/src/Hyperion.Tests/testfiles/mixed_test_file_.netcoreappversionv5.0.tf differ diff --git a/src/Hyperion.Tests/testfiles/mixed_test_file_.netframeworkversionv4.6.1.tf b/src/Hyperion.Tests/testfiles/mixed_test_file_.netframeworkversionv4.6.1.tf index 8de4aed3..1649be19 100644 Binary files a/src/Hyperion.Tests/testfiles/mixed_test_file_.netframeworkversionv4.6.1.tf and b/src/Hyperion.Tests/testfiles/mixed_test_file_.netframeworkversionv4.6.1.tf differ diff --git a/src/Hyperion/Extensions/TypeEx.cs b/src/Hyperion/Extensions/TypeEx.cs index c917417f..1ad02766 100644 --- a/src/Hyperion/Extensions/TypeEx.cs +++ b/src/Hyperion/Extensions/TypeEx.cs @@ -118,18 +118,16 @@ private static Type GetTypeFromManifestName(Stream stream, DeserializerSession s return TypeNameLookup.GetOrAdd(byteArr, b => { var shortName = StringEx.FromUtf8Bytes(b.Bytes, 0, b.Bytes.Length); -#if NET45 - if (shortName.Contains("System.Private.CoreLib,%core%")) - { - shortName = shortName.Replace("System.Private.CoreLib,%core%", "mscorlib,%core%"); - } -#endif -#if NETSTANDARD - if (shortName.Contains("mscorlib,%core%")) + var overrides = session.Serializer.Options.CrossFrameworkPackageNameOverrides; + + var oldName = shortName; + foreach (var adapter in overrides) { - shortName = shortName.Replace("mscorlib,%core%", "System.Private.CoreLib,%core%"); + shortName = adapter(shortName); + if (!ReferenceEquals(oldName, shortName)) + break; } -#endif + return LoadTypeByName(shortName); }); } diff --git a/src/Hyperion/SerializerOptions.cs b/src/Hyperion/SerializerOptions.cs index 31a0c620..098ecb4b 100644 --- a/src/Hyperion/SerializerOptions.cs +++ b/src/Hyperion/SerializerOptions.cs @@ -16,6 +16,22 @@ namespace Hyperion { public class SerializerOptions { + internal static List> DefaultPackageNameOverrides() + { + return new List> + { +#if NET45 + str => str.Contains("System.Private.CoreLib,%core%") + ? str.Replace("System.Private.CoreLib,%core%", "mscorlib,%core%") + : str +#elif NETSTANDARD + str => str.Contains("mscorlib,%core%") + ? str.Replace("mscorlib,%core%", "System.Private.CoreLib,%core%") + : str +#endif + }; + } + internal static readonly Surrogate[] EmptySurrogates = new Surrogate[0]; @@ -53,8 +69,10 @@ public class SerializerOptions internal readonly bool VersionTolerance; internal readonly Type[] KnownTypes; internal readonly Dictionary KnownTypesDict = new Dictionary(); + internal readonly List> CrossFrameworkPackageNameOverrides = + DefaultPackageNameOverrides(); - public SerializerOptions(bool versionTolerance = false, bool preserveObjectReferences = false, IEnumerable surrogates = null, IEnumerable serializerFactories = null, IEnumerable knownTypes = null, bool ignoreISerializable = false) + public SerializerOptions(bool versionTolerance = false, bool preserveObjectReferences = false, IEnumerable surrogates = null, IEnumerable serializerFactories = null, IEnumerable knownTypes = null, bool ignoreISerializable = false, IEnumerable> packageNameOverrides = null) { VersionTolerance = versionTolerance; Surrogates = surrogates?.ToArray() ?? EmptySurrogates; @@ -72,6 +90,9 @@ public SerializerOptions(bool versionTolerance = false, bool preserveObjectRefer PreserveObjectReferences = preserveObjectReferences; IgnoreISerializable = ignoreISerializable; + + if(packageNameOverrides != null) + CrossFrameworkPackageNameOverrides.AddRange(packageNameOverrides); } } } \ No newline at end of file diff --git a/src/common.props b/src/common.props index 5e5fa18e..f0ab5fde 100644 --- a/src/common.props +++ b/src/common.props @@ -2,12 +2,16 @@ Copyright © 2016-2017 Akka.NET Team Akka.NET Team - 0.9.16 - [Bump Microsoft.NET.Test.Sdk from 16.5.0 to 16.6.1](https://github.com/akkadotnet/Hyperion/pull/174) -[Add deserialization support for ReadOnlyDictionary](https://github.com/akkadotnet/Hyperion/pull/177) -[Bump FluentAssertions from 5.10.2 to 5.10.3](https://github.com/akkadotnet/Hyperion/pull/171) -[Bump System.Collections.Immutable from 1.7.0 to 1.7.1](https://github.com/akkadotnet/Hyperion/pull/175) -[Bump BenchmarkDotNet from 0.12.0 to 0.12.1](https://github.com/akkadotnet/Hyperion/pull/172) + 0.9.17 + [Bump Microsoft.NET.Test.Sdk from 16.6.1 to 16.7.1](https://github.com/akkadotnet/Hyperion/pull/182) +[Fix unit test problem](https://github.com/akkadotnet/Hyperion/pull/191) +[Bump FSharp.Core from 4.7.2 to 5.0.0](https://github.com/akkadotnet/Hyperion/pull/189) +[Fix issue #40 regarding partial streams](https://github.com/akkadotnet/Hyperion/pull/185) +[Fix Hyperion not using known serializers when defined](https://github.com/akkadotnet/Hyperion/pull/184) +[Bump Microsoft.NET.Test.Sdk from 16.7.1 to 16.8.3](https://github.com/akkadotnet/Hyperion/pull/196) +[Bump System.Collections.Immutable from 1.7.1 to 5.0.0](https://github.com/akkadotnet/Hyperion/pull/195) +[Bump FSharp.Core from 5.0.0 to 5.0.1](https://github.com/akkadotnet/Hyperion/pull/202) +[Update the cross framework spec to include complex POCO object, Type serialization, and support for netcoreapp3.1 and net5.0](https://github.com/akkadotnet/Hyperion/pull/204) http://getakka.net/images/akkalogo.png https://github.com/akkadotnet/Hyperion https://github.com/akkadotnet/Hyperion/blob/master/LICENSE @@ -16,7 +20,7 @@ 2.4.1 2.4.3 - 16.9.1 + 16.9.4 1.2.2 \ No newline at end of file