-
Notifications
You must be signed in to change notification settings - Fork 109
Expand file tree
/
Copy pathCompositeSerializationBinder.cs
More file actions
75 lines (63 loc) · 2.81 KB
/
CompositeSerializationBinder.cs
File metadata and controls
75 lines (63 loc) · 2.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
using System;
using System.Reflection;
using System.Runtime.Serialization;
using Composite.Core.Types;
using Newtonsoft.Json.Serialization;
namespace Composite.Core.Serialization
{
/// <summary>
/// Removes temporary assembly references when serializing references to generated classes.
/// </summary>
internal class CompositeSerializationBinder: DefaultSerializationBinder
{
private const string GeneratedTypesNamespacePrefix = "CompositeGenerated.";
private const string GeneratedTypesAssemblyName = "Composite.Generated";
public static SerializationBinder Instance { get; } = new CompositeSerializationBinder();
public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
typeName = serializedType.FullName;
if (typeName.StartsWith(GeneratedTypesNamespacePrefix, StringComparison.OrdinalIgnoreCase)
&& Guid.TryParse(serializedType.Assembly.GetName().Name, out _))
{
assemblyName = GeneratedTypesAssemblyName;
}
else
{
assemblyName = serializedType.Assembly.FullName;
}
}
public override Type BindToType(string assemblyName, string typeName)
{
if (assemblyName == GeneratedTypesAssemblyName
&& typeName.StartsWith(GeneratedTypesNamespacePrefix, StringComparison.OrdinalIgnoreCase))
{
var result = TypeManager.TryGetType($"{typeName}, {assemblyName}") ?? TypeManager.TryGetType(typeName);
if (result != null) return result;
}
ValidateTypeIsSupported(assemblyName, typeName);
return base.BindToType(assemblyName, typeName);
}
private void ValidateTypeIsSupported(string assemblyName, string typeName)
{
assemblyName = new AssemblyName(assemblyName).Name;
if (assemblyName == "Composite"
|| assemblyName.StartsWith("Composite.")
|| assemblyName.StartsWith("Orckestra."))
{
return;
}
if (assemblyName != typeof(object).Assembly.GetName().Name /* "mscorlib" */)
throw new NotSupportedException($"Not supported assembly name '{assemblyName}'");
var dotOffset = typeName.LastIndexOf(".", StringComparison.Ordinal);
if (dotOffset > 0)
{
string ns = typeName.Substring(0, dotOffset);
if (ns == nameof(System) || ns.StartsWith("System.Collections"))
{
return;
}
}
throw new NotSupportedException("Not supported object type");
}
}
}