ProxyObjectReference
Handles the deserialization of proxies.
using Castle.DynamicProxy.Generators;
using Castle.DynamicProxy.Generators.Emitters;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
namespace Castle.DynamicProxy.Serialization
{
[Serializable]
public class ProxyObjectReference : IObjectReference, ISerializable, IDeserializationCallback
{
private static ModuleScope scope = new ModuleScope();
private readonly SerializationInfo info;
private readonly StreamingContext context;
private readonly Type baseType;
private readonly Type[] interfaces;
private readonly object proxy;
private readonly ProxyGenerationOptions proxyGenerationOptions;
private bool isInterfaceProxy;
private bool delegateToBase;
public static ModuleScope ModuleScope => scope;
public static void ResetScope()
{
SetScope(new ModuleScope());
}
public static void SetScope(ModuleScope scope)
{
if (scope == null)
throw new ArgumentNullException("scope");
ProxyObjectReference.scope = scope;
}
protected ProxyObjectReference(SerializationInfo info, StreamingContext context)
{
this.info = info;
this.context = context;
baseType = DeserializeTypeFromString("__baseType");
string[] array = (string[])info.GetValue("__interfaces", typeof(string[]));
interfaces = new Type[array.Length];
for (int i = 0; i < array.Length; i++) {
interfaces[i] = Type.GetType(array[i]);
}
proxyGenerationOptions = (ProxyGenerationOptions)info.GetValue("__proxyGenerationOptions", typeof(ProxyGenerationOptions));
proxy = RecreateProxy();
DeserializeProxyState();
}
private Type DeserializeTypeFromString(string key)
{
return Type.GetType(info.GetString(key), true, false);
}
protected virtual object RecreateProxy()
{
string value = GetValue<string>("__proxyTypeId");
if (value.Equals(ProxyTypeConstants.Class)) {
isInterfaceProxy = false;
return RecreateClassProxy();
}
if (value.Equals(ProxyTypeConstants.ClassWithTarget)) {
isInterfaceProxy = false;
return RecreateClassProxyWithTarget();
}
isInterfaceProxy = true;
return RecreateInterfaceProxy(value);
}
private object RecreateClassProxyWithTarget()
{
ClassProxyWithTargetGenerator classProxyWithTargetGenerator = new ClassProxyWithTargetGenerator(scope, baseType, interfaces, proxyGenerationOptions);
Type generatedType = classProxyWithTargetGenerator.GetGeneratedType();
return InstantiateClassProxy(generatedType);
}
public object RecreateInterfaceProxy(string generatorType)
{
Type interface = DeserializeTypeFromString("__theInterface");
Type proxyTargetType = DeserializeTypeFromString("__targetFieldType");
InterfaceProxyWithTargetGenerator interfaceProxyWithTargetGenerator;
if (generatorType == ProxyTypeConstants.InterfaceWithTarget)
interfaceProxyWithTargetGenerator = new InterfaceProxyWithTargetGenerator(scope, interface);
else if (generatorType == ProxyTypeConstants.InterfaceWithoutTarget) {
interfaceProxyWithTargetGenerator = new InterfaceProxyWithoutTargetGenerator(scope, interface);
} else {
if (!(generatorType == ProxyTypeConstants.InterfaceWithTargetInterface))
throw new InvalidOperationException($"""{generatorType}""");
interfaceProxyWithTargetGenerator = new InterfaceProxyWithTargetInterfaceGenerator(scope, interface);
}
Type type = interfaceProxyWithTargetGenerator.GenerateCode(proxyTargetType, interfaces, proxyGenerationOptions);
return FormatterServices.GetSafeUninitializedObject(type);
}
public object RecreateClassProxy()
{
ClassProxyGenerator classProxyGenerator = new ClassProxyGenerator(scope, baseType);
Type proxy_type = classProxyGenerator.GenerateCode(interfaces, proxyGenerationOptions);
return InstantiateClassProxy(proxy_type);
}
private object InstantiateClassProxy(Type proxy_type)
{
delegateToBase = GetValue<bool>("__delegateToBase");
if (delegateToBase)
return Activator.CreateInstance(proxy_type, info, context);
return FormatterServices.GetSafeUninitializedObject(proxy_type);
}
protected void InvokeCallback(object target)
{
if (target is IDeserializationCallback)
(target as IDeserializationCallback).OnDeserialization(this);
}
public object GetRealObject(StreamingContext context)
{
return proxy;
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
}
public void OnDeserialization(object sender)
{
IInterceptor[] value = GetValue<IInterceptor[]>("__interceptors");
SetInterceptors(value);
DeserializeProxyMembers();
DeserializeProxyState();
InvokeCallback(proxy);
}
private void DeserializeProxyMembers()
{
Type type = proxy.GetType();
MemberInfo[] serializableMembers = FormatterServices.GetSerializableMembers(type);
List<MemberInfo> list = new List<MemberInfo>();
List<object> list2 = new List<object>();
for (int i = 0; i < serializableMembers.Length; i++) {
FieldInfo fieldInfo = serializableMembers[i] as FieldInfo;
if ((object)fieldInfo.DeclaringType == type) {
object value = info.GetValue(fieldInfo.Name, fieldInfo.FieldType);
list.Add(fieldInfo);
list2.Add(value);
}
}
FormatterServices.PopulateObjectMembers(proxy, list.ToArray(), list2.ToArray());
}
private void DeserializeProxyState()
{
if (isInterfaceProxy) {
object value = GetValue<object>("__target");
SetTarget(value);
} else if (!delegateToBase) {
object[] value2 = GetValue<object[]>("__data");
MemberInfo[] serializableMembers = FormatterServices.GetSerializableMembers(baseType);
serializableMembers = TypeUtil.Sort(serializableMembers);
FormatterServices.PopulateObjectMembers(proxy, serializableMembers, value2);
}
}
private void SetTarget(object target)
{
FieldInfo field = proxy.GetType().GetField("__target");
if ((object)field == null)
throw new SerializationException("The SerializationInfo specifies an invalid interface proxy type, which has no __target field.");
field.SetValue(proxy, target);
}
private void SetInterceptors(IInterceptor[] interceptors)
{
FieldInfo field = proxy.GetType().GetField("__interceptors");
if ((object)field == null)
throw new SerializationException("The SerializationInfo specifies an invalid proxy type, which has no __interceptors field.");
field.SetValue(proxy, interceptors);
}
private T GetValue<T>(string name)
{
return (T)info.GetValue(name, typeof(T));
}
}
}