using System; using System.Globalization; using System.Reflection; using System.Runtime.Serialization; using DPumpHydr.WinFrmUI.WenSkin.Json.Utilities; namespace DPumpHydr.WinFrmUI.WenSkin.Json.Serialization { /// /// The default serialization binder used when resolving and loading classes from type names. /// public class DefaultSerializationBinder : SerializationBinder { internal struct TypeNameKey : IEquatable { internal readonly string AssemblyName; internal readonly string TypeName; public TypeNameKey(string assemblyName, string typeName) { AssemblyName = assemblyName; TypeName = typeName; } public override int GetHashCode() { return ((AssemblyName != null) ? AssemblyName.GetHashCode() : 0) ^ ((TypeName != null) ? TypeName.GetHashCode() : 0); } public override bool Equals(object obj) { if (!(obj is TypeNameKey)) { return false; } return Equals((TypeNameKey)obj); } public bool Equals(TypeNameKey other) { if (AssemblyName == other.AssemblyName) { return TypeName == other.TypeName; } return false; } } internal static readonly DefaultSerializationBinder Instance = new DefaultSerializationBinder(); private readonly ThreadSafeStore _typeCache = new ThreadSafeStore(GetTypeFromTypeNameKey); private static Type GetTypeFromTypeNameKey(TypeNameKey typeNameKey) { string assemblyName = typeNameKey.AssemblyName; string typeName = typeNameKey.TypeName; if (assemblyName != null) { Assembly assembly = Assembly.LoadWithPartialName(assemblyName); if (assembly == null) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly2 in assemblies) { if (assembly2.FullName == assemblyName) { assembly = assembly2; break; } } } if (assembly == null) { throw new JsonSerializationException("Could not load assembly '{0}'.".FormatWith(CultureInfo.InvariantCulture, assemblyName)); } Type type = assembly.GetType(typeName); if (type == null) { throw new JsonSerializationException("Could not find type '{0}' in assembly '{1}'.".FormatWith(CultureInfo.InvariantCulture, typeName, assembly.FullName)); } return type; } return Type.GetType(typeName); } /// /// When overridden in a derived class, controls the binding of a serialized object to a type. /// /// Specifies the name of the serialized object. /// Specifies the name of the serialized object. /// /// The type of the object the formatter creates a new instance of. /// public override Type BindToType(string assemblyName, string typeName) { return _typeCache.Get(new TypeNameKey(assemblyName, typeName)); } /// /// When overridden in a derived class, controls the binding of a serialized object to a type. /// /// The type of the object the formatter creates a new instance of. /// Specifies the name of the serialized object. /// Specifies the name of the serialized object. public override void BindToName(Type serializedType, out string assemblyName, out string typeName) { assemblyName = serializedType.Assembly.FullName; typeName = serializedType.FullName; } } }