Skip to content

Commit

Permalink
Fix cross framework incompatibility for System.Drawing.Color (#208)
Browse files Browse the repository at this point in the history
* Fix cross framework problem with System.Drawing

* Merge PR #206 test case

* Generalize type package name transformation for cross framework compatibility

* Define compiler directives that are missing in CI/CD

* Change class based configuration to lambda function
  • Loading branch information
Arkatufus authored Apr 13, 2021
1 parent bd3a432 commit 477b5f3
Show file tree
Hide file tree
Showing 15 changed files with 104 additions and 20 deletions.
16 changes: 15 additions & 1 deletion src/Hyperion.Tests/Bugs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -24,7 +25,7 @@
namespace Hyperion.Tests
{

public class Bugs
public class Bugs : TestBase
{
private readonly ITestOutputHelper _output;

Expand Down Expand Up @@ -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<Color>();
Assert.Equal(expected, actual);
}

#endregion

public class SnapshotSelectionCriteria
{
Expand Down
18 changes: 16 additions & 2 deletions src/Hyperion.Tests/CrossFrameworkSerializationTests.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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<Func<string, string>>
{
str => str.Contains("System.Drawing.Primitives") ? str.Replace(".Primitives", "") : str
}));
#elif NETCOREAPP
_serializer = new Serializer();
#endif
}

public static IEnumerable<object[]> SerializationFiles()
Expand Down
11 changes: 11 additions & 0 deletions src/Hyperion.Tests/Generator/CrossFrameworkClass.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Drawing;

namespace Hyperion.Tests.Generator
{
Expand Down Expand Up @@ -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))
Expand Down
9 changes: 9 additions & 0 deletions src/Hyperion.Tests/Generator/CrossFrameworkInitializer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Drawing;

namespace Hyperion.Tests.Generator
{
Expand All @@ -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()
};
}
Expand Down
13 changes: 13 additions & 0 deletions src/Hyperion.Tests/Hyperion.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
<StartupObject>Hyperion.Tests.Generator.Program</StartupObject>
</PropertyGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' or '$(TargetFramework)' == 'net5.0' ">
<DefineConstants>$(DefineConstants);NETCOREAPP</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == 'net461' ">
<DefineConstants>$(DefineConstants);NETFX</DefineConstants>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="5.10.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
Expand All @@ -22,4 +30,9 @@
<ProjectReference Include="..\Hyperion\Hyperion.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net461'">
<Reference Include="System.Drawing">
<Private>true</Private>
</Reference>
</ItemGroup>
</Project>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
18 changes: 8 additions & 10 deletions src/Hyperion/Extensions/TypeEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
}
Expand Down
23 changes: 22 additions & 1 deletion src/Hyperion/SerializerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,22 @@ namespace Hyperion
{
public class SerializerOptions
{
internal static List<Func<string, string>> DefaultPackageNameOverrides()
{
return new List<Func<string, string>>
{
#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];


Expand Down Expand Up @@ -53,8 +69,10 @@ public class SerializerOptions
internal readonly bool VersionTolerance;
internal readonly Type[] KnownTypes;
internal readonly Dictionary<Type, ushort> KnownTypesDict = new Dictionary<Type, ushort>();
internal readonly List<Func<string, string>> CrossFrameworkPackageNameOverrides =
DefaultPackageNameOverrides();

public SerializerOptions(bool versionTolerance = false, bool preserveObjectReferences = false, IEnumerable<Surrogate> surrogates = null, IEnumerable<ValueSerializerFactory> serializerFactories = null, IEnumerable<Type> knownTypes = null, bool ignoreISerializable = false)
public SerializerOptions(bool versionTolerance = false, bool preserveObjectReferences = false, IEnumerable<Surrogate> surrogates = null, IEnumerable<ValueSerializerFactory> serializerFactories = null, IEnumerable<Type> knownTypes = null, bool ignoreISerializable = false, IEnumerable<Func<string, string>> packageNameOverrides = null)
{
VersionTolerance = versionTolerance;
Surrogates = surrogates?.ToArray() ?? EmptySurrogates;
Expand All @@ -72,6 +90,9 @@ public SerializerOptions(bool versionTolerance = false, bool preserveObjectRefer

PreserveObjectReferences = preserveObjectReferences;
IgnoreISerializable = ignoreISerializable;

if(packageNameOverrides != null)
CrossFrameworkPackageNameOverrides.AddRange(packageNameOverrides);
}
}
}
16 changes: 10 additions & 6 deletions src/common.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@
<PropertyGroup>
<Copyright>Copyright © 2016-2017 Akka.NET Team</Copyright>
<Authors>Akka.NET Team</Authors>
<VersionPrefix>0.9.16</VersionPrefix>
<PackageReleaseNotes>[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)</PackageReleaseNotes>
<VersionPrefix>0.9.17</VersionPrefix>
<PackageReleaseNotes>[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)</PackageReleaseNotes>
<PackageIconUrl>http://getakka.net/images/akkalogo.png</PackageIconUrl>
<PackageProjectUrl>https://github.com/akkadotnet/Hyperion</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/akkadotnet/Hyperion/blob/master/LICENSE</PackageLicenseUrl>
Expand Down

0 comments on commit 477b5f3

Please sign in to comment.