diff --git a/MessageCommunicator.TestGui/Data/_ByteStreamSettings/ByteStreamHandlerSerialPortSettings.cs b/MessageCommunicator.TestGui/Data/_ByteStreamSettings/ByteStreamHandlerSerialPortSettings.cs index 976907b..f68dcda 100644 --- a/MessageCommunicator.TestGui/Data/_ByteStreamSettings/ByteStreamHandlerSerialPortSettings.cs +++ b/MessageCommunicator.TestGui/Data/_ByteStreamSettings/ByteStreamHandlerSerialPortSettings.cs @@ -8,6 +8,7 @@ namespace MessageCommunicator.TestGui.Data { + [TypeAlias("ByteStreamHandlerSerialPortSettings")] public class ByteStreamHandlerSerialPortSettings : IByteStreamHandlerAppSettings { private const string CATEGORY = "Serial Port"; diff --git a/MessageCommunicator.TestGui/Data/_ByteStreamSettings/ByteStreamHandlerTcpSettings.cs b/MessageCommunicator.TestGui/Data/_ByteStreamSettings/ByteStreamHandlerTcpSettings.cs index 490e8b3..d1447c8 100644 --- a/MessageCommunicator.TestGui/Data/_ByteStreamSettings/ByteStreamHandlerTcpSettings.cs +++ b/MessageCommunicator.TestGui/Data/_ByteStreamSettings/ByteStreamHandlerTcpSettings.cs @@ -7,6 +7,7 @@ namespace MessageCommunicator.TestGui.Data { + [TypeAlias("ByteStreamHandlerTcpSettings")] public class ByteStreamHandlerTcpSettings : IByteStreamHandlerAppSettings { private const string CATEGORY = "Tcp"; diff --git a/MessageCommunicator.TestGui/Data/_ByteStreamSettings/ByteStreamHandlerUdpSettings.cs b/MessageCommunicator.TestGui/Data/_ByteStreamSettings/ByteStreamHandlerUdpSettings.cs index 746b531..7fa57c4 100644 --- a/MessageCommunicator.TestGui/Data/_ByteStreamSettings/ByteStreamHandlerUdpSettings.cs +++ b/MessageCommunicator.TestGui/Data/_ByteStreamSettings/ByteStreamHandlerUdpSettings.cs @@ -6,6 +6,7 @@ namespace MessageCommunicator.TestGui.Data { + [TypeAlias("ByteStreamHandlerUdpSettings")] public class ByteStreamHandlerUdpSettings : IByteStreamHandlerAppSettings { private const string CATEGORY = "Udp"; diff --git a/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerByUnderlyingPackageSettings.cs b/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerByUnderlyingPackageSettings.cs index de5d94d..5f22edf 100644 --- a/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerByUnderlyingPackageSettings.cs +++ b/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerByUnderlyingPackageSettings.cs @@ -5,6 +5,7 @@ namespace MessageCommunicator.TestGui.Data { + [TypeAlias("MessageRecognizerByUnderlyingPackageSettings")] public class MessageRecognizerByUnderlyingPackageSettings : IMessageRecognizerAppSettings { private const string CATEGORY = "ByUnderlyingPackage Recognizer"; diff --git a/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerDefaultSettings.cs b/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerDefaultSettings.cs index e18094d..c94f8ff 100644 --- a/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerDefaultSettings.cs +++ b/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerDefaultSettings.cs @@ -5,6 +5,7 @@ namespace MessageCommunicator.TestGui.Data { + [TypeAlias("MessageRecognizerDefaultSettings")] public class MessageRecognizerDefaultSettings : IMessageRecognizerAppSettings { private const string CATEGORY = "Default Recognizer"; diff --git a/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerEndSymbolSettings.cs b/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerEndSymbolSettings.cs index b020dde..06f89f1 100644 --- a/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerEndSymbolSettings.cs +++ b/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerEndSymbolSettings.cs @@ -5,6 +5,7 @@ namespace MessageCommunicator.TestGui.Data { + [TypeAlias("MessageRecognizerEndSymbolSettings")] public class MessageRecognizerEndSymbolSettings : IMessageRecognizerAppSettings { private const string CATEGORY = "EndSymbol Recognizer"; diff --git a/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerFixedLengthAndEndSymbolsSettings.cs b/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerFixedLengthAndEndSymbolsSettings.cs index df6d2f4..e86a105 100644 --- a/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerFixedLengthAndEndSymbolsSettings.cs +++ b/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerFixedLengthAndEndSymbolsSettings.cs @@ -5,6 +5,7 @@ namespace MessageCommunicator.TestGui.Data { + [TypeAlias("MessageRecognizerFixedLengthAndEndSymbolsSettings")] public class MessageRecognizerFixedLengthAndEndSymbolsSettings : IMessageRecognizerAppSettings { private const string CATEGORY = "FixedLength and EndSymbols Recognizer"; diff --git a/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerFixedLengthSettings.cs b/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerFixedLengthSettings.cs index f68f4ec..e50ff51 100644 --- a/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerFixedLengthSettings.cs +++ b/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerFixedLengthSettings.cs @@ -5,6 +5,7 @@ namespace MessageCommunicator.TestGui.Data { + [TypeAlias("MessageRecognizerFixedLengthSettings")] public class MessageRecognizerFixedLengthSettings : IMessageRecognizerAppSettings { private const string CATEGORY = "FixedLength Recognizer"; diff --git a/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerStartAndEndSymbolSettings.cs b/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerStartAndEndSymbolSettings.cs index f931c4d..724d382 100644 --- a/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerStartAndEndSymbolSettings.cs +++ b/MessageCommunicator.TestGui/Data/_RecognizerSettings/MessageRecognizerStartAndEndSymbolSettings.cs @@ -5,6 +5,7 @@ namespace MessageCommunicator.TestGui.Data { + [TypeAlias("MessageRecognizerStartAndEndSymbolSettings")] public class MessageRecognizerStartAndEndSymbolSettings : IMessageRecognizerAppSettings { private const string CATEGORY = "Start- and EndSymbol Recognizer"; diff --git a/MessageCommunicator.TestGui/_Util/_Misc.cs b/MessageCommunicator.TestGui/_Util/_Misc.cs new file mode 100644 index 0000000..678f18b --- /dev/null +++ b/MessageCommunicator.TestGui/_Util/_Misc.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MessageCommunicator.TestGui +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] + public class TypeAliasAttribute : Attribute + { + public string AliasName { get; } + + public TypeAliasAttribute(string aliasName) + { + this.AliasName = aliasName; + } + } +} diff --git a/MessageCommunicator.TestGui/_Util/_Serialization/DynamicMappingWithAliasSerializationBinder.cs b/MessageCommunicator.TestGui/_Util/_Serialization/DynamicMappingWithAliasSerializationBinder.cs new file mode 100644 index 0000000..a13c11f --- /dev/null +++ b/MessageCommunicator.TestGui/_Util/_Serialization/DynamicMappingWithAliasSerializationBinder.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace MessageCommunicator.TestGui +{ + public class DynamicMappingWithAliasSerializationBinder : DefaultSerializationBinder + { + private const string ASSEMBLY_ALIAS = "__alias"; + + private ResolveTypeByAliasDelegate _typeResolver; + + public DynamicMappingWithAliasSerializationBinder(ResolveTypeByAliasDelegate typeResolver) + { + _typeResolver = typeResolver; + } + + public override void BindToName(Type serializedType, out string assemblyName, out string typeName) + { + var aliasAttrib = serializedType.GetCustomAttribute(); + if (aliasAttrib == null) + { + throw new JsonSerializationException( + $"Unable to serialize type {serializedType.FullName} because dynamic mapping is only supported for types with {nameof(TypeAliasAttribute)}!"); + } + + if (serializedType.IsGenericType) + { + throw new JsonSerializationException( + $"Unable to serialize type {serializedType.FullName} because dynamic mapping of generic types is not supported!"); + } + + assemblyName = ASSEMBLY_ALIAS; + typeName = aliasAttrib.AliasName; + } + + public override Type BindToType(string? assemblyName, string typeName) + { + if (assemblyName != ASSEMBLY_ALIAS) + { + throw new JsonSerializationException($"Unable to load type {typeName} from assembly {assemblyName}: Dynamic resolving only available for alias names!"); + } + + var resolvedType = _typeResolver(typeName); + if (resolvedType == null) + { + throw new JsonSerializationException($"Unable to load type {typeName} from assembly {assemblyName}!"); + } + + return resolvedType; + } + } +} diff --git a/MessageCommunicator.TestGui/_Util/SerializationHelper.cs b/MessageCommunicator.TestGui/_Util/_Serialization/SerializationHelper.cs similarity index 59% rename from MessageCommunicator.TestGui/_Util/SerializationHelper.cs rename to MessageCommunicator.TestGui/_Util/_Serialization/SerializationHelper.cs index 96f64bf..07f25ae 100644 --- a/MessageCommunicator.TestGui/_Util/SerializationHelper.cs +++ b/MessageCommunicator.TestGui/_Util/_Serialization/SerializationHelper.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.IO; +using System.Reflection; +using System.Reflection.Metadata.Ecma335; using System.Text; using Newtonsoft.Json; @@ -12,8 +14,27 @@ public static class SerializationHelper static SerializationHelper() { + Dictionary typesByAlias = new Dictionary(16); + foreach (var actType in Assembly.GetExecutingAssembly().GetTypes()) + { + var aliasAttrib = actType.GetCustomAttribute(); + if(aliasAttrib == null){ continue; } + + typesByAlias[aliasAttrib.AliasName] = actType; + } + + Serializer = new JsonSerializer(); Serializer.TypeNameHandling = TypeNameHandling.Auto; + Serializer.SerializationBinder = new DynamicMappingWithAliasSerializationBinder( + (aliasName) => + { + if (typesByAlias.TryGetValue(aliasName, out var foundType)) + { + return foundType; + } + return null; + }); } public static T? DeserializeFromStream(Stream inStream) diff --git a/MessageCommunicator.TestGui/_Util/_Serialization/_Misc.cs b/MessageCommunicator.TestGui/_Util/_Serialization/_Misc.cs new file mode 100644 index 0000000..3b6615d --- /dev/null +++ b/MessageCommunicator.TestGui/_Util/_Serialization/_Misc.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MessageCommunicator.TestGui +{ + public delegate Type? ResolveTypeByAliasDelegate(string aliasName); +}