<PackageReference Include="Castle.Core" Version="3.0.0.3001" />

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