private static void ImplementGetIdentifier( TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField, System.Type parentType) { /* * get * { * if (this.__lazyInitializer == null) * return base.get_<Identifier>(); * return (<ReturnType>)this.__lazyInitializer.Identifier; * } */ var methodOverride = ProxyBuilderHelper.GenerateMethodSignature(method.Name, method, typeBuilder); var IL = methodOverride.GetILGenerator(); EmitCallBaseIfLazyInitializerIsNull(IL, method, lazyInitializerField, parentType); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, lazyInitializerField); IL.Emit(OpCodes.Callvirt, LazyInitializerIdentifierProperty.GetMethod); IL.Emit(OpCodes.Unbox_Any, method.ReturnType); IL.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodOverride, method); }
public TypeInfo CreateProxyType(System.Type baseType, IReadOnlyCollection <System.Type> baseInterfaces) { var typeName = $"{baseType.Name}Proxy"; var assemblyName = $"{typeName}Assembly"; var moduleName = $"{typeName}Module"; var name = new AssemblyName(assemblyName); var assemblyBuilder = ProxyBuilderHelper.DefineDynamicAssembly(AppDomain.CurrentDomain, name); var moduleBuilder = ProxyBuilderHelper.DefineDynamicModule(assemblyBuilder, moduleName); const TypeAttributes typeAttributes = TypeAttributes.AutoClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.BeforeFieldInit; var interfaces = new HashSet <System.Type> { // Add the ISerializable interface so that it can be implemented typeof(ISerializable) }; interfaces.UnionWith(baseInterfaces); interfaces.UnionWith(baseInterfaces.SelectMany(i => i.GetInterfaces())); interfaces.UnionWith(baseType.GetInterfaces()); // Use the object as the base type // since we're not inheriting from any class type var parentType = baseType; if (baseType.IsInterface) { parentType = typeof(object); interfaces.Add(baseType); } interfaces.RemoveWhere(i => !i.IsVisible); var typeBuilder = moduleBuilder.DefineType(typeName, typeAttributes, parentType, interfaces.ToArray()); var lazyInitializerField = typeBuilder.DefineField("__lazyInitializer", LazyInitializerType, FieldAttributes.Private); var proxyInfoField = typeBuilder.DefineField("__proxyInfo", typeof(NHibernateProxyFactoryInfo), FieldAttributes.Private); ImplementConstructor(typeBuilder, parentType, lazyInitializerField, proxyInfoField); // Provide a custom implementation of ISerializable instead of redirecting it back to the interceptor foreach (var method in ProxyBuilderHelper.GetProxiableMethods(baseType, interfaces.Except(new[] { typeof(ISerializable) }))) { CreateProxiedMethod(typeBuilder, method, lazyInitializerField); } ProxyBuilderHelper.MakeProxySerializable(typeBuilder); ImplementDeserializationConstructor(typeBuilder, parentType); ImplementGetObjectData(typeBuilder, proxyInfoField, lazyInitializerField); var proxyType = typeBuilder.CreateTypeInfo(); ProxyBuilderHelper.Save(assemblyBuilder); return(proxyType); }
public static TypeInfo CreateProxyType(System.Type baseType) { // Avoid having a suffix ending with "Proxy", for disambiguation with INHibernateProxy proxies var typeName = $"{baseType.Name}ProxyForFieldInterceptor"; var assemblyName = $"{typeName}Assembly"; var moduleName = $"{typeName}Module"; var name = new AssemblyName(assemblyName); var assemblyBuilder = ProxyBuilderHelper.DefineDynamicAssembly(AppDomain.CurrentDomain, name); var moduleBuilder = ProxyBuilderHelper.DefineDynamicModule(assemblyBuilder, moduleName); const TypeAttributes typeAttributes = TypeAttributes.AutoClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.BeforeFieldInit; var interfaces = new HashSet <System.Type> { typeof(IFieldInterceptorAccessor), typeof(ISerializable) }; // Use the object as the base type // since we're not inheriting from any class type var parentType = baseType; if (baseType.IsInterface) { throw new ArgumentException( $"Field interceptor proxy does not support being build on an interface baseType ({baseType.FullName}).", nameof(baseType)); } interfaces.RemoveWhere(i => !i.IsVisible); var typeBuilder = moduleBuilder.DefineType(typeName, typeAttributes, parentType, interfaces.ToArray()); var fieldInterceptorField = typeBuilder.DefineField("__fieldInterceptor", FieldInterceptorType, FieldAttributes.Private); var proxyInfoField = typeBuilder.DefineField("__proxyInfo", typeof(NHibernateProxyFactoryInfo), FieldAttributes.Private); ImplementConstructor(typeBuilder, parentType, proxyInfoField); // Provide a custom implementation of ISerializable instead of redirecting it back to the interceptor foreach (var method in ProxyBuilderHelper.GetProxiableMethods(baseType, interfaces.Except(new[] { typeof(ISerializable) }))) { CreateProxiedMethod(typeBuilder, method, fieldInterceptorField); } ProxyBuilderHelper.MakeProxySerializable(typeBuilder); ImplementDeserializationConstructor(typeBuilder, parentType); ImplementGetObjectData(typeBuilder, proxyInfoField, fieldInterceptorField, parentType); var proxyType = typeBuilder.CreateTypeInfo(); ProxyBuilderHelper.Save(assemblyBuilder); return(proxyType); }
private static void ImplementISerializable( TypeBuilder typeBuilder, FieldInfo proxyInfoField, FieldInfo fieldInterceptorField, System.Type baseType) { ProxyBuilderHelper.MakeProxySerializable(typeBuilder); ImplementDeserializationConstructor(typeBuilder, baseType); ImplementGetObjectData(typeBuilder, proxyInfoField, fieldInterceptorField, baseType); }
private static void ImplementSet(TypeBuilder typeBuilder, MethodInfo setter, FieldInfo fieldInterceptorField) { /* * if (this.__fieldInterceptor != null) * { * this.__fieldInterceptor.MarkDirty(); * this.__fieldInterceptor.Intercept(this, <ReflectHelper.GetPropertyName(setter)>, value, true); * } * base.<setter>(value); */ var methodOverride = ProxyBuilderHelper.GenerateMethodSignature(setter.Name, setter, typeBuilder); var IL = methodOverride.GetILGenerator(); // if (this.__fieldInterceptor != null) IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, fieldInterceptorField); IL.Emit(OpCodes.Ldnull); var skipInterceptor = IL.DefineLabel(); IL.Emit(OpCodes.Beq, skipInterceptor); // this.__fieldInterceptor.MarkDirty(); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, fieldInterceptorField); IL.Emit(OpCodes.Callvirt, FieldInterceptorMarkDirtyMethod); // this.__fieldInterceptor.Intercept(this, <ReflectHelper.GetPropertyName(setter)>, propValue, true); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, fieldInterceptorField); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldstr, ReflectHelper.GetPropertyName(setter)); IL.Emit(OpCodes.Ldarg_1); var propertyType = setter.GetParameters()[0].ParameterType; if (propertyType.IsValueType) { IL.Emit(OpCodes.Box, propertyType); } IL.Emit(OpCodes.Ldc_I4_1); IL.EmitCall(OpCodes.Call, FieldInterceptorInterceptExtensionMethod, null); IL.Emit(OpCodes.Pop); // end if (this.__fieldInterceptor != null) IL.MarkLabel(skipInterceptor); // base.<setter>(value); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldarg_1); IL.Emit(OpCodes.Call, setter); IL.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodOverride, setter); }
public static TypeInfo CreateProxyType(System.Type baseType) { if (baseType.IsInterface) { throw new ArgumentException( $"Field interceptor proxy does not support being build on an interface baseType ({baseType.FullName}).", nameof(baseType)); } // Avoid having a suffix ending with "Proxy", for disambiguation with INHibernateProxy proxies var typeName = $"{baseType.Name}ProxyForFieldInterceptor"; var assemblyName = $"{typeName}Assembly"; var moduleName = $"{typeName}Module"; var name = new AssemblyName(assemblyName); var assemblyBuilder = ProxyBuilderHelper.DefineDynamicAssembly(AppDomain.CurrentDomain, name); #if NETFX || NETCOREAPP2_0 if (!baseType.IsVisible) { ProxyBuilderHelper.GenerateInstanceOfIgnoresAccessChecksToAttribute(assemblyBuilder, baseType.Assembly.GetName().Name); } #endif var moduleBuilder = ProxyBuilderHelper.DefineDynamicModule(assemblyBuilder, moduleName); const TypeAttributes typeAttributes = TypeAttributes.AutoClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.BeforeFieldInit; var interfaces = new[] { typeof(IFieldInterceptorAccessor), typeof(ISerializable) }; var typeBuilder = moduleBuilder.DefineType(typeName, typeAttributes, baseType, interfaces); var fieldInterceptorField = typeBuilder.DefineField("__fieldInterceptor", FieldInterceptorType, FieldAttributes.Private); var proxyInfoField = typeBuilder.DefineField("__proxyInfo", typeof(NHibernateProxyFactoryInfo), FieldAttributes.Private); ImplementConstructor(typeBuilder, baseType, proxyInfoField); foreach (var method in ProxyBuilderHelper.GetProxiableMethods(baseType)) { CreateProxiedMethod(typeBuilder, method, fieldInterceptorField); } ImplementIFieldInterceptorAccessor(typeBuilder, fieldInterceptorField); ImplementISerializable(typeBuilder, proxyInfoField, fieldInterceptorField, baseType); var proxyType = typeBuilder.CreateTypeInfo(); ProxyBuilderHelper.Save(assemblyBuilder); return(proxyType); }
private static void ImplementDeserializationConstructor(TypeBuilder typeBuilder, System.Type parentType) { var parameterTypes = new[] { typeof(SerializationInfo), typeof(StreamingContext) }; var constructor = typeBuilder.DefineConstructor(constructorAttributes, CallingConventions.Standard, parameterTypes); constructor.SetImplementationFlags(MethodImplAttributes.IL | MethodImplAttributes.Managed); var IL = constructor.GetILGenerator(); ProxyBuilderHelper.CallDefaultBaseConstructor(IL, parentType); //Everything is done in NHibernateProxyObjectReference, so just return data. IL.Emit(OpCodes.Ret); }
private static void ImplementConstructor(TypeBuilder typeBuilder, System.Type parentType, FieldInfo proxyInfoField) { var constructor = typeBuilder.DefineConstructor(constructorAttributes, CallingConventions.Standard, new[] { typeof(NHibernateProxyFactoryInfo) }); constructor.SetImplementationFlags(MethodImplAttributes.IL | MethodImplAttributes.Managed); var IL = constructor.GetILGenerator(); ProxyBuilderHelper.CallDefaultBaseConstructor(IL, parentType); // __proxyInfo == proxyInfo; IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldarg_1); IL.Emit(OpCodes.Stfld, proxyInfoField); IL.Emit(OpCodes.Ret); }
private static void ImplementCallMethodOnImplementation(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) { /* * if (this.__lazyInitializer == null) * return base.<Method>(args..); * return this.__lazyInitializer.GetImplementation().<Method>(args..) */ var methodOverride = ProxyBuilderHelper.GenerateMethodSignature(method.Name, method, typeBuilder); var IL = methodOverride.GetILGenerator(); EmitCallBaseIfLazyInitializerIsNull(IL, method, lazyInitializerField); EmitCallImplementation(IL, method, lazyInitializerField); IL.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodOverride, method); }
private static void ImplementDeserializationConstructor(TypeBuilder typeBuilder, System.Type parentType) { var parameterTypes = new[] { typeof(SerializationInfo), typeof(StreamingContext) }; var constructor = typeBuilder.DefineConstructor(constructorAttributes, CallingConventions.Standard, parameterTypes); constructor.SetImplementationFlags(MethodImplAttributes.IL | MethodImplAttributes.Managed); var IL = constructor.GetILGenerator(); if (typeof(ISerializable).IsAssignableFrom(parentType)) { var baseConstructor = parentType.GetConstructor( BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, parameterTypes, null); if (baseConstructor == null) { // Throw new InvalidOperationException(<message>); IL.Emit( OpCodes.Ldstr, $"Proxy for class {parentType.FullName} cannot be deserialized because the class implements " + $"{nameof(ISerializable)} without having a deserialization constructor (see CA2229)."); IL.Emit(OpCodes.Newobj, InvalidOperationWithMessageConstructor); IL.Emit(OpCodes.Throw); } else { IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldarg_1); IL.Emit(OpCodes.Ldarg_2); IL.Emit(OpCodes.Call, baseConstructor); } } else { ProxyBuilderHelper.CallDefaultBaseConstructor(IL, parentType); } // Everything else is done in FieldInterceptorObjectReference. IL.Emit(OpCodes.Ret); }
private static void ImplementCallMethodOnEmbeddedComponentId(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) { /* * if (this.__lazyInitializer == null) * return base.<Method>(args..); * this.__lazyInitializer.Identifier.<Method>(args..); */ var methodOverride = ProxyBuilderHelper.GenerateMethodSignature(method.Name, method, typeBuilder); var IL = methodOverride.GetILGenerator(); EmitCallBaseIfLazyInitializerIsNull(IL, method, lazyInitializerField); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, lazyInitializerField); IL.Emit(OpCodes.Callvirt, LazyInitializerIdentifierProperty.GetMethod); IL.Emit(OpCodes.Unbox_Any, method.DeclaringType); EmitCallMethod(IL, OpCodes.Callvirt, method); IL.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodOverride, method); }
private static void ImplementGetObjectData(TypeBuilder typeBuilder, FieldInfo proxyInfoField, FieldInfo lazyInitializerField) { var methodBuilder = ProxyBuilderHelper.GetObjectDataMethodBuilder(typeBuilder); var IL = methodBuilder.GetILGenerator(); // info.SetType(typeof(NHibernateProxyObjectReference)); IL.Emit(OpCodes.Ldarg_1); IL.Emit(OpCodes.Ldtoken, typeof(NHibernateProxyObjectReference)); IL.Emit(OpCodes.Call, ReflectionCache.TypeMethods.GetTypeFromHandle); IL.Emit(OpCodes.Callvirt, ProxyBuilderHelper.SerializationInfoSetTypeMethod); // (new NHibernateProxyObjectReference(this.__proxyInfo, this.__lazyInitializer.Identifier)).GetObjectData(info, context); //this.__proxyInfo IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, proxyInfoField); //this.__lazyInitializer.Identifier IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, lazyInitializerField); IL.Emit(OpCodes.Callvirt, LazyInitializerIdentifierProperty.GetMethod); var constructor = typeof(NHibernateProxyObjectReference).GetConstructor( new[] { typeof(NHibernateProxyFactoryInfo), typeof(object), }); IL.Emit(OpCodes.Newobj, constructor); IL.Emit(OpCodes.Ldarg_1); IL.Emit(OpCodes.Ldarg_2); IL.Emit(OpCodes.Callvirt, ProxyBuilderHelper.SerializableGetObjectDataMethod); IL.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodBuilder, ProxyBuilderHelper.SerializableGetObjectDataMethod); }
private static void ImplementSetIdentifier( TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField, System.Type parentType) { /* * set * { * if (this.__lazyInitializer == null) * return base.set_<Identifier>(value); * this.__lazyInitializer.Initialize(); * this.__lazyInitializer.Identifier = value; * this.__lazyInitializer.GetImplementation().<Identifier> = value; * } */ var propertyType = method.GetParameters()[0].ParameterType; var methodOverride = ProxyBuilderHelper.GenerateMethodSignature(method.Name, method, typeBuilder); var IL = methodOverride.GetILGenerator(); EmitCallBaseIfLazyInitializerIsNull(IL, method, lazyInitializerField, parentType); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, lazyInitializerField); IL.Emit(OpCodes.Callvirt, LazyInitializerInitializeMethod); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, lazyInitializerField); IL.Emit(OpCodes.Ldarg_1); if (propertyType.IsValueType) { IL.Emit(OpCodes.Box, propertyType); } IL.Emit(OpCodes.Callvirt, LazyInitializerIdentifierProperty.SetMethod); EmitCallImplementation(IL, method, lazyInitializerField); IL.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodOverride, method); }
private static void ImplementGet(TypeBuilder typeBuilder, MethodInfo getter, FieldInfo fieldInterceptorField) { /* * var propValue = base.<getter>(); * if (this.__fieldInterceptor != null) * { * var result = this.__fieldInterceptor.Intercept(this, <ReflectHelper.GetPropertyName(getter)>, propValue); * * if (result != AbstractFieldInterceptor.InvokeImplementation) * { * return (<getter.ReturnType>)result; * } * } * return propValue; */ var methodOverride = ProxyBuilderHelper.GenerateMethodSignature(getter.Name, getter, typeBuilder); var IL = methodOverride.GetILGenerator(); IL.DeclareLocal(getter.ReturnType); // propValue IL.DeclareLocal(typeof(object)); // result // var propValue = base.<getter>(); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Call, getter); IL.Emit(OpCodes.Stloc_0); // if (this.__fieldInterceptor != null) IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, fieldInterceptorField); IL.Emit(OpCodes.Ldnull); var skipInterceptor = IL.DefineLabel(); IL.Emit(OpCodes.Beq, skipInterceptor); // var result = this.__fieldInterceptor.Intercept(this, <ReflectHelper.GetPropertyName(getter)>, propValue); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, fieldInterceptorField); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldstr, ReflectHelper.GetPropertyName(getter)); IL.Emit(OpCodes.Ldloc_0); if (getter.ReturnType.IsValueType) { IL.Emit(OpCodes.Box, getter.ReturnType); } IL.Emit(OpCodes.Callvirt, FieldInterceptorInterceptMethod); IL.Emit(OpCodes.Stloc_1); // if (result != AbstractFieldInterceptor.InvokeImplementation) IL.Emit(OpCodes.Ldloc_1); IL.Emit(OpCodes.Ldsfld, AbstractFieldInterceptorInvokeImplementationField); var skipInterceptorResult = IL.DefineLabel(); IL.Emit(OpCodes.Beq, skipInterceptorResult); // return (<getter.ReturnType>)result; IL.Emit(OpCodes.Ldloc_1); IL.Emit(OpCodes.Unbox_Any, getter.ReturnType); IL.Emit(OpCodes.Ret); // end if (result != AbstractFieldInterceptor.InvokeImplementation) IL.MarkLabel(skipInterceptorResult); // end if (this.__fieldInterceptor != null) IL.MarkLabel(skipInterceptor); // return propValue; IL.Emit(OpCodes.Ldloc_0); IL.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodOverride, getter); }
private static void ImplementGetObjectData(TypeBuilder typeBuilder, FieldInfo proxyInfoField, FieldInfo fieldInterceptorField, System.Type parentType) { var methodBuilder = ProxyBuilderHelper.GetObjectDataMethodBuilder(typeBuilder); var IL = methodBuilder.GetILGenerator(); IL.DeclareLocal(FieldInterceptorObjectReferenceType); // info.SetType(<FieldInterceptorObjectReferenceType>); IL.Emit(OpCodes.Ldarg_1); IL.Emit(OpCodes.Ldtoken, FieldInterceptorObjectReferenceType); IL.Emit(OpCodes.Call, ReflectionCache.TypeMethods.GetTypeFromHandle); IL.Emit(OpCodes.Callvirt, ProxyBuilderHelper.SerializationInfoSetTypeMethod); // var objectReference = new FieldInterceptorObjectReference(this.__proxyInfo, this.__fieldInterceptor)); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, proxyInfoField); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, fieldInterceptorField); IL.Emit(OpCodes.Newobj, FieldInterceptorObjectReferenceConstructor); IL.Emit(OpCodes.Stloc_0); // objectReference.GetObjectData(info, context); IL.Emit(OpCodes.Ldloc_0); IL.Emit(OpCodes.Ldarg_1); IL.Emit(OpCodes.Ldarg_2); IL.Emit(OpCodes.Callvirt, ProxyBuilderHelper.SerializableGetObjectDataMethod); if (typeof(ISerializable).IsAssignableFrom(parentType)) { var parentGetObjectData = parentType.GetMethod( nameof(ISerializable.GetObjectData), BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(SerializationInfo), typeof(StreamingContext) }, null); if (parentGetObjectData == null) { // Throw new InvalidOperationException(<message>); IL.Emit( OpCodes.Ldstr, $"Proxy for class {parentType.FullName} cannot be serialized because the class implements " + $"{nameof(ISerializable)} without having a public or protected GetObjectData."); IL.Emit(OpCodes.Newobj, InvalidOperationWithMessageConstructor); IL.Emit(OpCodes.Throw); typeBuilder.DefineMethodOverride(methodBuilder, ProxyBuilderHelper.SerializableGetObjectDataMethod); return; } // base.GetObjectData(info, context); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldarg_1); IL.Emit(OpCodes.Ldarg_2); IL.Emit(OpCodes.Call, parentGetObjectData); // objectReference.SetNoAdditionalData(info); IL.Emit(OpCodes.Ldloc_0); IL.Emit(OpCodes.Ldarg_1); IL.Emit(OpCodes.Callvirt, FieldInterceptorObjectReferenceSetNoAdditionalDataMethod); } else { // objectReference.SerializeBaseData(info, context, this, <parentType>); IL.Emit(OpCodes.Ldloc_0); IL.Emit(OpCodes.Ldarg_1); IL.Emit(OpCodes.Ldarg_2); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldtoken, parentType); IL.Emit(OpCodes.Call, ReflectionCache.TypeMethods.GetTypeFromHandle); IL.Emit(OpCodes.Callvirt, FieldInterceptorObjectReferenceGetBaseDataMethod); } IL.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodBuilder, ProxyBuilderHelper.SerializableGetObjectDataMethod); }
public TypeInfo CreateProxyType(System.Type baseType, IReadOnlyCollection <System.Type> baseInterfaces) { System.Type interfaceType = null; if (baseType == typeof(object)) { // Mapping option "proxy" allows to ask for using an interface, which switches the base type to object // and adds the interface to base interfaces set. // Avoids using object for naming the proxy, as otherwise all entities using the "proxy" option for // specifying an interface would have their proxies sharing the same full name. interfaceType = baseInterfaces.FirstOrDefault(i => i != typeof(INHibernateProxy)); } var typeName = $"{(interfaceType ?? baseType).Name}Proxy"; var assemblyName = $"{typeName}Assembly"; var moduleName = $"{typeName}Module"; var name = new AssemblyName(assemblyName); var assemblyBuilder = ProxyBuilderHelper.DefineDynamicAssembly(AppDomain.CurrentDomain, name); var moduleBuilder = ProxyBuilderHelper.DefineDynamicModule(assemblyBuilder, moduleName); const TypeAttributes typeAttributes = TypeAttributes.AutoClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.BeforeFieldInit; var interfaces = new HashSet <System.Type> { // Add the ISerializable interface so that it can be implemented typeof(ISerializable) }; interfaces.UnionWith(baseInterfaces); interfaces.UnionWith(baseInterfaces.SelectMany(i => i.GetInterfaces())); interfaces.UnionWith(baseType.GetInterfaces()); // Use the object as the base type // since we're not inheriting from any class type var parentType = baseType; if (baseType.IsInterface) { parentType = typeof(object); interfaces.Add(baseType); } #if NETFX || NETCOREAPP2_0 var assemblyNamesToIgnoreAccessCheck = new[] { baseType } .Concat(interfaces).Where(i => !i.IsVisible) .Select(i => i.Assembly.GetName().Name) .Distinct(); foreach (var a in assemblyNamesToIgnoreAccessCheck) { ProxyBuilderHelper.GenerateInstanceOfIgnoresAccessChecksToAttribute(assemblyBuilder, a); } #else interfaces.RemoveWhere(i => !i.IsVisible); #endif var typeBuilder = moduleBuilder.DefineType(typeName, typeAttributes, parentType, interfaces.ToArray()); var lazyInitializerField = typeBuilder.DefineField("__lazyInitializer", LazyInitializerType, FieldAttributes.Private); var proxyInfoField = typeBuilder.DefineField("__proxyInfo", typeof(NHibernateProxyFactoryInfo), FieldAttributes.Private); ImplementConstructor(typeBuilder, parentType, lazyInitializerField, proxyInfoField); // Provide a custom implementation of ISerializable instead of redirecting it back to the interceptor foreach (var method in ProxyBuilderHelper.GetProxiableMethods(baseType, interfaces.Except(new[] { typeof(ISerializable) }))) { CreateProxiedMethod(typeBuilder, method, lazyInitializerField, parentType); } ProxyBuilderHelper.MakeProxySerializable(typeBuilder); ImplementDeserializationConstructor(typeBuilder, parentType); ImplementGetObjectData(typeBuilder, proxyInfoField, lazyInitializerField); var proxyType = typeBuilder.CreateTypeInfo(); ProxyBuilderHelper.Save(assemblyBuilder); return(proxyType); }
private static void ImplementGetObjectData(TypeBuilder typeBuilder, FieldInfo proxyInfoField, FieldInfo lazyInitializerField) { var methodBuilder = ProxyBuilderHelper.GetObjectDataMethodBuilder(typeBuilder); var IL = methodBuilder.GetILGenerator(); // info.SetType(typeof(NHibernateProxyObjectReference)); IL.Emit(OpCodes.Ldarg_1); IL.Emit(OpCodes.Ldtoken, typeof(NHibernateProxyObjectReference)); IL.Emit(OpCodes.Call, ReflectionCache.TypeMethods.GetTypeFromHandle); IL.Emit(OpCodes.Callvirt, ProxyBuilderHelper.SerializationInfoSetTypeMethod); // return // (new NHibernateProxyObjectReference( // this.__proxyInfo, // this.__lazyInitializer.Identifier), // this.__lazyInitializer.IsUninitialized ? null : this.__lazyInitializer.GetImplementation()) // .GetObjectData(info, context); //this.__proxyInfo IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, proxyInfoField); //this.__lazyInitializer.Identifier IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, lazyInitializerField); IL.Emit(OpCodes.Callvirt, LazyInitializerIdentifierProperty.GetMethod); // this.__lazyInitializer.IsUninitialized ? null : this.__lazyInitializer.GetImplementation() var isUnitialized = IL.DefineLabel(); var endIsUnitializedTernary = IL.DefineLabel(); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, lazyInitializerField); IL.Emit(OpCodes.Callvirt, LazyInitializerIsUninitializedProperty.GetMethod); IL.Emit(OpCodes.Brtrue, isUnitialized); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, lazyInitializerField); IL.Emit(OpCodes.Callvirt, LazyInitializerGetImplementationMethod); IL.Emit(OpCodes.Br, endIsUnitializedTernary); IL.MarkLabel(isUnitialized); IL.Emit(OpCodes.Ldnull); IL.MarkLabel(endIsUnitializedTernary); var constructor = typeof(NHibernateProxyObjectReference).GetConstructor( new[] { typeof(NHibernateProxyFactoryInfo), typeof(object), typeof(object) }); IL.Emit(OpCodes.Newobj, constructor); IL.Emit(OpCodes.Ldarg_1); IL.Emit(OpCodes.Ldarg_2); IL.Emit(OpCodes.Callvirt, ProxyBuilderHelper.SerializableGetObjectDataMethod); IL.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodBuilder, ProxyBuilderHelper.SerializableGetObjectDataMethod); }