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;
}
}
}