From c48beb8c9d06c83ad1f0897ae0aa1410feefa357 Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Sat, 9 Dec 2017 00:08:47 +1300 Subject: [PATCH 1/7] Implement new StaticProxyFactoryFactory - The factory generates high-efficient static proxies (no interceptor) --- .../Lightweight/BytecodeProviderFixture.cs | 2 +- .../Bytecode/AbstractBytecodeProvider.cs | 5 +- .../Bytecode/StaticProxyFactoryFactory.cs | 17 + .../DynamicProxy/DefaultProxyMethodBuilder.cs | 2 +- .../Proxy/DynamicProxy/ProxyFactory.cs | 14 +- src/NHibernate/Proxy/LiteLazyInitializer.cs | 17 + .../Proxy/NHibernateProxyBuilder.cs | 369 ++++++++++++++++++ .../Proxy/NHibernateProxyFactoryInfo.cs | 58 +++ .../Proxy/NHibernateProxyObjectReference.cs | 38 ++ src/NHibernate/Proxy/StaticProxyFactory.cs | 51 +++ 10 files changed, 562 insertions(+), 11 deletions(-) create mode 100644 src/NHibernate/Bytecode/StaticProxyFactoryFactory.cs create mode 100644 src/NHibernate/Proxy/LiteLazyInitializer.cs create mode 100644 src/NHibernate/Proxy/NHibernateProxyBuilder.cs create mode 100644 src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs create mode 100644 src/NHibernate/Proxy/NHibernateProxyObjectReference.cs create mode 100644 src/NHibernate/Proxy/StaticProxyFactory.cs diff --git a/src/NHibernate.Test/Bytecode/Lightweight/BytecodeProviderFixture.cs b/src/NHibernate.Test/Bytecode/Lightweight/BytecodeProviderFixture.cs index a721fc6f2e6..31d4ca7432e 100644 --- a/src/NHibernate.Test/Bytecode/Lightweight/BytecodeProviderFixture.cs +++ b/src/NHibernate.Test/Bytecode/Lightweight/BytecodeProviderFixture.cs @@ -14,7 +14,7 @@ public void NotConfiguredProxyFactoryFactory() { var bcp = new BytecodeProviderImpl(); IProxyFactoryFactory p = bcp.ProxyFactoryFactory; - Assert.That(p, Is.InstanceOf()); + Assert.That(p, Is.InstanceOf()); } [Test] diff --git a/src/NHibernate/Bytecode/AbstractBytecodeProvider.cs b/src/NHibernate/Bytecode/AbstractBytecodeProvider.cs index 16c7fcd6468..8c6f19a7da2 100644 --- a/src/NHibernate/Bytecode/AbstractBytecodeProvider.cs +++ b/src/NHibernate/Bytecode/AbstractBytecodeProvider.cs @@ -28,7 +28,8 @@ public virtual IProxyFactoryFactory ProxyFactoryFactory throw new HibernateByteCodeException("Failed to create an instance of '" + proxyFactoryFactory.FullName + "'!", e); } } - return new DefaultProxyFactoryFactory(); + + return StaticProxyFactoryFactory.Instance; } } @@ -116,4 +117,4 @@ public void SetCollectionTypeFactoryClass(System.Type type) #endregion } -} \ No newline at end of file +} diff --git a/src/NHibernate/Bytecode/StaticProxyFactoryFactory.cs b/src/NHibernate/Bytecode/StaticProxyFactoryFactory.cs new file mode 100644 index 00000000000..d3d9a912f15 --- /dev/null +++ b/src/NHibernate/Bytecode/StaticProxyFactoryFactory.cs @@ -0,0 +1,17 @@ +using NHibernate.Proxy; + +namespace NHibernate.Bytecode +{ + public class StaticProxyFactoryFactory : IProxyFactoryFactory + { + internal static StaticProxyFactoryFactory Instance = new StaticProxyFactoryFactory(); + + public IProxyFactory BuildProxyFactory() => new StaticProxyFactory(); + + public IProxyValidator ProxyValidator => new DynProxyTypeValidator(); + + public bool IsInstrumented(System.Type entityClass) => true; + + public bool IsProxy(object entity) => entity is INHibernateProxy; + } +} diff --git a/src/NHibernate/Proxy/DynamicProxy/DefaultProxyMethodBuilder.cs b/src/NHibernate/Proxy/DynamicProxy/DefaultProxyMethodBuilder.cs index c999aa10086..0e8249d2466 100644 --- a/src/NHibernate/Proxy/DynamicProxy/DefaultProxyMethodBuilder.cs +++ b/src/NHibernate/Proxy/DynamicProxy/DefaultProxyMethodBuilder.cs @@ -30,7 +30,7 @@ public DefaultyProxyMethodBuilder(IMethodBodyEmitter emitter) public IMethodBodyEmitter MethodBodyEmitter { get; private set; } - private static MethodBuilder GenerateMethodSignature(string name, MethodInfo method, TypeBuilder typeBuilder) + internal static MethodBuilder GenerateMethodSignature(string name, MethodInfo method, TypeBuilder typeBuilder) { //TODO: Should we use attributes of base method? var methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual; diff --git a/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs b/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs index 4f35eb0d35a..675e34ba013 100644 --- a/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs +++ b/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs @@ -21,11 +21,11 @@ public sealed class ProxyFactory { internal static readonly ConcurrentDictionary _cache = new ConcurrentDictionary(); - private static readonly ConstructorInfo defaultBaseConstructor = typeof(object).GetConstructor(new System.Type[0]); + internal static readonly ConstructorInfo defaultBaseConstructor = typeof(object).GetConstructor(new System.Type[0]); private static readonly MethodInfo getValue = ReflectHelper.GetMethod( si => si.GetValue(null, null)); - private static readonly MethodInfo setType = ReflectHelper.GetMethod( + internal static readonly MethodInfo setType = ReflectHelper.GetMethod( si => si.SetType(null)); private static readonly MethodInfo addValue = ReflectHelper.GetMethod( si => si.AddValue(null, null)); @@ -129,7 +129,7 @@ private TypeInfo CreateUncachedProxyType(System.Type baseType, IReadOnlyCollecti return proxyType; } - private IEnumerable GetProxiableMethods(System.Type type, IEnumerable interfaces) + internal static IEnumerable GetProxiableMethods(System.Type type, IEnumerable interfaces) { const BindingFlags candidateMethodsBindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; return @@ -139,7 +139,7 @@ private IEnumerable GetProxiableMethods(System.Type type, IEnumerabl .Distinct(); } - private static ConstructorBuilder DefineConstructor(TypeBuilder typeBuilder, System.Type parentType) + internal static ConstructorBuilder DefineConstructor(TypeBuilder typeBuilder, System.Type parentType) { const MethodAttributes constructorAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | @@ -166,7 +166,7 @@ private static ConstructorBuilder DefineConstructor(TypeBuilder typeBuilder, Sys return constructor; } - private static void ImplementGetObjectData(System.Type baseType, IReadOnlyCollection baseInterfaces, TypeBuilder typeBuilder, FieldInfo interceptorField) + internal static void ImplementGetObjectData(System.Type baseType, IReadOnlyCollection baseInterfaces, TypeBuilder typeBuilder, FieldInfo interceptorField) { const MethodAttributes attributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual; @@ -217,7 +217,7 @@ private static void ImplementGetObjectData(System.Type baseType, IReadOnlyCollec IL.Emit(OpCodes.Ret); } - private static void DefineSerializationConstructor(TypeBuilder typeBuilder, FieldInfo interceptorField, ConstructorBuilder defaultConstructor) + internal static void DefineSerializationConstructor(TypeBuilder typeBuilder, FieldInfo interceptorField, ConstructorBuilder defaultConstructor) { const MethodAttributes constructorAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | @@ -254,7 +254,7 @@ private static void DefineSerializationConstructor(TypeBuilder typeBuilder, Fiel IL.Emit(OpCodes.Ret); } - private static void AddSerializationSupport(System.Type baseType, IReadOnlyCollection baseInterfaces, TypeBuilder typeBuilder, FieldInfo interceptorField, ConstructorBuilder defaultConstructor) + internal static void AddSerializationSupport(System.Type baseType, IReadOnlyCollection baseInterfaces, TypeBuilder typeBuilder, FieldInfo interceptorField, ConstructorBuilder defaultConstructor) { ConstructorInfo serializableConstructor = typeof(SerializableAttribute).GetConstructor(new System.Type[0]); var customAttributeBuilder = new CustomAttributeBuilder(serializableConstructor, new object[0]); diff --git a/src/NHibernate/Proxy/LiteLazyInitializer.cs b/src/NHibernate/Proxy/LiteLazyInitializer.cs new file mode 100644 index 00000000000..c4340aeba1a --- /dev/null +++ b/src/NHibernate/Proxy/LiteLazyInitializer.cs @@ -0,0 +1,17 @@ +using System; +using NHibernate.Engine; + +namespace NHibernate.Proxy +{ + [Serializable] + sealed class LiteLazyInitializer : AbstractLazyInitializer + { + internal LiteLazyInitializer(string entityName, object id, ISessionImplementor session, System.Type persistentClass) + : base(entityName, id, session) + { + PersistentClass = persistentClass; + } + + public override System.Type PersistentClass { get; } + } +} diff --git a/src/NHibernate/Proxy/NHibernateProxyBuilder.cs b/src/NHibernate/Proxy/NHibernateProxyBuilder.cs new file mode 100644 index 00000000000..12935ed421f --- /dev/null +++ b/src/NHibernate/Proxy/NHibernateProxyBuilder.cs @@ -0,0 +1,369 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.Serialization; +using System.Security; +using NHibernate.Proxy.DynamicProxy; +using NHibernate.Type; +using NHibernate.Util; + +namespace NHibernate.Proxy +{ + class NHibernateProxyBuilder + { + const MethodAttributes InterceptorMethodsAttributes = MethodAttributes.Private | MethodAttributes.Final | MethodAttributes.HideBySig | + MethodAttributes.SpecialName | MethodAttributes.NewSlot | MethodAttributes.Virtual; + + const string HibernateLazyInitializerFieldName = nameof(INHibernateProxy.HibernateLazyInitializer); + + const MethodAttributes constructorAttributes = MethodAttributes.Public | + MethodAttributes.HideBySig | MethodAttributes.SpecialName | + MethodAttributes.RTSpecialName; + + static readonly System.Type NHibernateProxyType = typeof(INHibernateProxy); + static readonly PropertyInfo NHibernateProxyTypeLazyInitializerProperty = NHibernateProxyType.GetProperty(HibernateLazyInitializerFieldName); + static readonly System.Type LazyInitializerType = typeof(ILazyInitializer); + static readonly PropertyInfo LazyInitializerIdentifierProperty = LazyInitializerType.GetProperty(nameof(ILazyInitializer.Identifier)); + static readonly MethodInfo LazyInitializerInitializeMethod = LazyInitializerType.GetMethod(nameof(ILazyInitializer.Initialize)); + static readonly MethodInfo LazyInitializerGetImplementationMethod = LazyInitializerType.GetMethod(nameof(ILazyInitializer.GetImplementation), System.Type.EmptyTypes); + static readonly IProxyAssemblyBuilder ProxyAssemblyBuilder = new DefaultProxyAssemblyBuilder(); + + static readonly ConstructorInfo SecurityCriticalAttributeConstructor = typeof(SecurityCriticalAttribute).GetConstructor(System.Type.EmptyTypes); + static readonly MethodInfo SerializableGetObjectDataMethod = typeof(ISerializable).GetMethod(nameof(ISerializable.GetObjectData)); + + readonly MethodInfo _getIdentifierMethod; + readonly MethodInfo _setIdentifierMethod; + readonly IAbstractComponentType _componentIdType; + readonly bool _overridesEquals; + public NHibernateProxyBuilder(MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, IAbstractComponentType componentIdType, bool overridesEquals) + { + _getIdentifierMethod = getIdentifierMethod; + _setIdentifierMethod = setIdentifierMethod; + _componentIdType = componentIdType; + _overridesEquals = overridesEquals; + } + + public TypeInfo CreateProxyType(System.Type baseType, IReadOnlyCollection baseInterfaces) + { + var typeName = $"{baseType.Name}Proxy"; + var assemblyName = $"{typeName}Assembly"; + var moduleName = $"{typeName}Module"; + + var name = new AssemblyName(assemblyName); + + var assemblyBuilder = ProxyAssemblyBuilder.DefineDynamicAssembly(AppDomain.CurrentDomain, name); + var moduleBuilder = ProxyAssemblyBuilder.DefineDynamicModule(assemblyBuilder, moduleName); + + const TypeAttributes typeAttributes = TypeAttributes.AutoClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.BeforeFieldInit; + + var interfaces = new HashSet + { + // 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); + } + + 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 ProxyFactory.GetProxiableMethods(baseType, interfaces.Except(new[] {typeof(ISerializable)}))) + { + CreateProxiedMethod(lazyInitializerField, method, typeBuilder); + } + + // Make the proxy serializable + var serializableConstructor = typeof(SerializableAttribute).GetConstructor(System.Type.EmptyTypes); + var customAttributeBuilder = new CustomAttributeBuilder(serializableConstructor, new object[0]); + typeBuilder.SetCustomAttribute(customAttributeBuilder); + + ImplementDeserializationConstructor(typeBuilder); + ImplementGetObjectData(typeBuilder, proxyInfoField); + + var proxyType = typeBuilder.CreateTypeInfo(); + + ProxyAssemblyBuilder.Save(assemblyBuilder); + + return proxyType; + } + + static void ImplementConstructor(TypeBuilder typeBuilder, System.Type parentType, FieldInfo lazyInitializerField, FieldInfo proxyInfoField) + { + var constructor = typeBuilder.DefineConstructor(constructorAttributes, CallingConventions.Standard, new[] {LazyInitializerType, typeof(NHibernateProxyFactoryInfo)}); + + var baseConstructor = parentType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, System.Type.EmptyTypes, null); + + // if there is no default constructor, or the default constructor is private/internal, call System.Object constructor + // this works, but the generated assembly will fail PeVerify (cannot use in medium trust for example) + if (baseConstructor == null || baseConstructor.IsPrivate || baseConstructor.IsAssembly) + baseConstructor = ProxyFactory.defaultBaseConstructor; + + var IL = constructor.GetILGenerator(); + + constructor.SetImplementationFlags(MethodImplAttributes.IL | MethodImplAttributes.Managed); + + IL.Emit(OpCodes.Ldarg_0); + IL.Emit(OpCodes.Call, baseConstructor); + + IL.Emit(OpCodes.Ldarg_0); + IL.Emit(OpCodes.Ldarg_1); + IL.Emit(OpCodes.Stfld, lazyInitializerField); + + IL.Emit(OpCodes.Ldarg_0); + IL.Emit(OpCodes.Ldarg_2); + IL.Emit(OpCodes.Stfld, proxyInfoField); + + IL.Emit(OpCodes.Ret); + } + + static void ImplementDeserializationConstructor(TypeBuilder typeBuilder) + { + 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(); + //Everything is done in NHibernateProxyObjectReference, so just return data. + IL.Emit(OpCodes.Ret); + } + + static void ImplementGetObjectData(TypeBuilder typeBuilder, FieldInfo proxyInfoField) + { + const MethodAttributes attributes = MethodAttributes.Public | MethodAttributes.HideBySig | + MethodAttributes.Virtual; + var parameterTypes = new[] {typeof (SerializationInfo), typeof (StreamingContext)}; + + var methodBuilder = typeBuilder.DefineMethod("GetObjectData", attributes, typeof (void), parameterTypes); + methodBuilder.SetCustomAttribute(new CustomAttributeBuilder(SecurityCriticalAttributeConstructor, Array.Empty())); + + var IL = methodBuilder.GetILGenerator(); + //LocalBuilder proxyBaseType = IL.DeclareLocal(typeof(Type)); + + // 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, ProxyFactory.setType); + + //this.__proxyInfo + IL.Emit(OpCodes.Ldarg_0); + IL.Emit(OpCodes.Ldfld, proxyInfoField); + + //this.LazyInitializer.Identifier + EmitGetLazyInitializer(IL); + 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, SerializableGetObjectDataMethod); + + IL.Emit(OpCodes.Ret); + + typeBuilder.DefineMethodOverride(methodBuilder, SerializableGetObjectDataMethod); + } + + public void CreateProxiedMethod(FieldInfo lazyInitializerField, MethodInfo method, TypeBuilder typeBuilder) + { + if (method == NHibernateProxyTypeLazyInitializerProperty.GetMethod) + { + ImplementGetLazyInitializer(typeBuilder, lazyInitializerField); + } + else if (method == _getIdentifierMethod) + { + ImplementGetIdentifier(typeBuilder, method); + } + else if (method == _setIdentifierMethod) + { + ImplementSetIdentifier(typeBuilder, method); + } + else if (!_overridesEquals && method.Name == "Equals" && method.GetBaseDefinition() == typeof(object).GetMethod("Equals", new[] {typeof(object)})) + { +//skip + } + else if (!_overridesEquals && method.Name == "GetHashCode" && method.GetBaseDefinition() == typeof(object).GetMethod("GetHashCode")) + { +//skip + } + else if (_componentIdType != null && _componentIdType.IsMethodOf(method)) + { + ImplementCallMethodOnEmbeddedComponentId(typeBuilder, method); + } + else + { + ImplementCallMethodOnImplementation(typeBuilder, method); + } + } + + static void ImplementGetLazyInitializer(TypeBuilder typeBuilder, FieldInfo lazyInitializerField) + { + // Implement the getter + var getMethod = typeBuilder.DefineMethod($"{NHibernateProxyType.FullName}.get_{HibernateLazyInitializerFieldName}", InterceptorMethodsAttributes, CallingConventions.HasThis, LazyInitializerType, System.Type.EmptyTypes); + getMethod.SetImplementationFlags(MethodImplAttributes.Managed | MethodImplAttributes.IL); + + var IL = getMethod.GetILGenerator(); + + // This is equivalent to: + // get { return __lazyInitializer; } + IL.Emit(OpCodes.Ldarg_0); + IL.Emit(OpCodes.Ldfld, lazyInitializerField); + IL.Emit(OpCodes.Ret); + + typeBuilder.DefineMethodOverride(getMethod, NHibernateProxyTypeLazyInitializerProperty.GetMethod); + + var property = typeBuilder.DefineProperty($"{NHibernateProxyType.FullName}.{HibernateLazyInitializerFieldName}", NHibernateProxyTypeLazyInitializerProperty.Attributes, LazyInitializerType, System.Type.EmptyTypes); + property.SetGetMethod(getMethod); + } + + static void ImplementGetIdentifier(TypeBuilder typeBuilder, MethodInfo method) + { + // get => return (ReturnType)((INHibernateProxy)this).LazyInitializer.Identifier; + var methodOverride = DefaultyProxyMethodBuilder.GenerateMethodSignature(method.Name, method, typeBuilder); + + var IL = methodOverride.GetILGenerator(); + + EmitCallBaseIfLazyInitializerIsNull(method, IL); + + EmitGetLazyInitializer(IL); + IL.Emit(OpCodes.Callvirt, LazyInitializerIdentifierProperty.GetMethod); + IL.Emit(OpCodes.Unbox_Any, method.ReturnType); + IL.Emit(OpCodes.Ret); + + typeBuilder.DefineMethodOverride(methodOverride, method); + } + + static void ImplementSetIdentifier(TypeBuilder typeBuilder, MethodInfo method) + { + /* + set + { + ((INHibernateLazyInitializer)this).LazyInitializer.Initialize(); + ((INHibernateLazyInitializer)this).LazyInitializer.Identifier = value; + ((INHibernateLazyInitializer)this).LazyInitializer.GetImplementation(). = value; + } + */ + var propertyType = method.GetParameters()[0].ParameterType; + var methodOverride = DefaultyProxyMethodBuilder.GenerateMethodSignature(method.Name, method, typeBuilder); + var IL = methodOverride.GetILGenerator(); + + EmitCallBaseIfLazyInitializerIsNull(method, IL); + + EmitGetLazyInitializer(IL); + IL.Emit(OpCodes.Callvirt, LazyInitializerInitializeMethod); + + EmitGetLazyInitializer(IL); + IL.Emit(OpCodes.Ldarg_1); + if (propertyType.IsValueType) + IL.Emit(OpCodes.Box, propertyType); + IL.Emit(OpCodes.Callvirt, LazyInitializerIdentifierProperty.SetMethod); + + EmitCallImplementation(method, IL); + + IL.Emit(OpCodes.Ret); + + typeBuilder.DefineMethodOverride(methodOverride, method); + } + + static void ImplementCallMethodOnEmbeddedComponentId(TypeBuilder typeBuilder, MethodInfo method) + { + // ((INHibernateProxy)this).LazyInitializer.Identifier.(args..); + var methodOverride = DefaultyProxyMethodBuilder.GenerateMethodSignature(method.Name, method, typeBuilder); + + var IL = methodOverride.GetILGenerator(); + + EmitCallBaseIfLazyInitializerIsNull(method, IL); + + EmitGetLazyInitializer(IL); + IL.Emit(OpCodes.Callvirt, LazyInitializerIdentifierProperty.GetMethod); + IL.Emit(OpCodes.Unbox_Any, method.DeclaringType); + EmitCallMethod(method, IL, OpCodes.Callvirt); + IL.Emit(OpCodes.Ret); + + typeBuilder.DefineMethodOverride(methodOverride, method); + } + + static void ImplementCallMethodOnImplementation(TypeBuilder typeBuilder, MethodInfo method) + { + /* + return ((INHibernateProxy)this).LazyInitializer.GetImplementation().(args..); + */ + var methodOverride = DefaultyProxyMethodBuilder.GenerateMethodSignature(method.Name, method, typeBuilder); + + var IL = methodOverride.GetILGenerator(); + + EmitCallBaseIfLazyInitializerIsNull(method, IL); + + EmitCallImplementation(method, IL); + IL.Emit(OpCodes.Ret); + + typeBuilder.DefineMethodOverride(methodOverride, method); + } + + static void EmitCallBaseIfLazyInitializerIsNull(MethodInfo method, ILGenerator IL) + { + //if (((INHibernateProxy) this).LazyInitializer == null) + // return base..< Method > (args..) + + EmitGetLazyInitializer(IL); + var skipBaseCall = IL.DefineLabel(); + + IL.Emit(OpCodes.Ldnull); + IL.Emit(OpCodes.Bne_Un, skipBaseCall); + + IL.Emit(OpCodes.Ldarg_0); + EmitCallMethod(method, IL, OpCodes.Call); + IL.Emit(OpCodes.Ret); + + IL.MarkLabel(skipBaseCall); + } + + static void EmitGetLazyInitializer(ILGenerator IL) + { + IL.Emit(OpCodes.Ldarg_0); + IL.Emit(OpCodes.Castclass, NHibernateProxyType); + IL.Emit(OpCodes.Callvirt, NHibernateProxyTypeLazyInitializerProperty.GetMethod); + } + + static void EmitCallMethod(MethodInfo method, ILGenerator IL, OpCode opCode) + { + for (var i = 0; i < method.GetParameters().Length; i++) + IL.Emit(OpCodes.Ldarg_S, (sbyte) (1 + i)); + IL.Emit(opCode, method); + } + + static void EmitCallImplementation(MethodInfo method, ILGenerator IL) + { + //((INHibernateLazyInitializer)this).LazyInitializer.GetImplementation().(args..); + EmitGetLazyInitializer(IL); + IL.Emit(OpCodes.Callvirt, LazyInitializerGetImplementationMethod); + IL.Emit(OpCodes.Unbox_Any, method.DeclaringType); + EmitCallMethod(method, IL, OpCodes.Callvirt); + } + } +} diff --git a/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs b/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs new file mode 100644 index 00000000000..8836eb6e84c --- /dev/null +++ b/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.Serialization; +using System.Security; +using NHibernate.Type; + +namespace NHibernate.Proxy +{ + [Serializable] + public sealed class NHibernateProxyFactoryInfo : ISerializable + { + readonly string _entityName; + readonly System.Type _persistentClass; + readonly System.Type[] _interfaces; + readonly MethodInfo _getIdentifierMethod; + readonly MethodInfo _setIdentifierMethod; + readonly IAbstractComponentType _componentIdType; + + internal NHibernateProxyFactoryInfo(string entityName, System.Type persistentClass, System.Type[] interfaces, MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, IAbstractComponentType componentIdType) + { + _entityName = entityName; + _persistentClass = persistentClass; + _interfaces = interfaces; + _getIdentifierMethod = getIdentifierMethod; + _setIdentifierMethod = setIdentifierMethod; + _componentIdType = componentIdType; + } + + public IProxyFactory CreateProxyFactory() + { + var factory = new DefaultProxyFactory(); + factory.PostInstantiate(_entityName, _persistentClass, new HashSet(_interfaces), _getIdentifierMethod, _setIdentifierMethod, _componentIdType); + return factory; + } + + NHibernateProxyFactoryInfo(SerializationInfo info, StreamingContext context) + { + _entityName = (string) info.GetValue(nameof(_entityName), typeof(string)); + _persistentClass = (System.Type) info.GetValue(nameof(_persistentClass), typeof(System.Type)); + _interfaces = (System.Type[]) info.GetValue(nameof(_interfaces), typeof(System.Type[])); + _getIdentifierMethod = (MethodInfo) info.GetValue(nameof(_getIdentifierMethod), typeof(MethodInfo)); + _setIdentifierMethod = (MethodInfo) info.GetValue(nameof(_setIdentifierMethod), typeof(MethodInfo)); + _componentIdType = (IAbstractComponentType) info.GetValue(nameof(_componentIdType), typeof(IAbstractComponentType)); + } + + [SecurityCritical] + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue(nameof(_entityName), _entityName); + info.AddValue(nameof(_persistentClass), _persistentClass); + info.AddValue(nameof(_interfaces), _interfaces); + info.AddValue(nameof(_getIdentifierMethod), _getIdentifierMethod); + info.AddValue(nameof(_setIdentifierMethod), _setIdentifierMethod); + info.AddValue(nameof(_componentIdType), _componentIdType); + } + } +} diff --git a/src/NHibernate/Proxy/NHibernateProxyObjectReference.cs b/src/NHibernate/Proxy/NHibernateProxyObjectReference.cs new file mode 100644 index 00000000000..2cc8e3a3354 --- /dev/null +++ b/src/NHibernate/Proxy/NHibernateProxyObjectReference.cs @@ -0,0 +1,38 @@ +using System; +using System.Runtime.Serialization; +using System.Security; + +namespace NHibernate.Proxy +{ + [Serializable] + public sealed class NHibernateProxyObjectReference : IObjectReference, ISerializable + { + readonly NHibernateProxyFactoryInfo _proxyFactoryInfo; + readonly object _identifier; + + public NHibernateProxyObjectReference(NHibernateProxyFactoryInfo proxyFactoryInfo, object identifier) + { + _proxyFactoryInfo = proxyFactoryInfo; + _identifier = identifier; + } + + NHibernateProxyObjectReference(SerializationInfo info, StreamingContext context) + { + _proxyFactoryInfo = (NHibernateProxyFactoryInfo) info.GetValue(nameof(_proxyFactoryInfo), typeof(NHibernateProxyFactoryInfo)); + _identifier = info.GetValue(nameof(_identifier), typeof(object)); + } + + [SecurityCritical] + public object GetRealObject(StreamingContext context) + { + return _proxyFactoryInfo.CreateProxyFactory().GetProxy(_identifier, null); + } + + [SecurityCritical] + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue(nameof(_proxyFactoryInfo), _proxyFactoryInfo); + info.AddValue(nameof(_identifier), _identifier); + } + } +} diff --git a/src/NHibernate/Proxy/StaticProxyFactory.cs b/src/NHibernate/Proxy/StaticProxyFactory.cs new file mode 100644 index 00000000000..264f2098730 --- /dev/null +++ b/src/NHibernate/Proxy/StaticProxyFactory.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Concurrent; +using System.Linq.Expressions; +using NHibernate.Engine; +using NHibernate.Intercept; +using NHibernate.Proxy.DynamicProxy; + +namespace NHibernate.Proxy +{ + public sealed class StaticProxyFactory : AbstractProxyFactory + { + static readonly ConcurrentDictionary> Cache = + new ConcurrentDictionary>(); + + static readonly INHibernateLogger Log = NHibernateLogger.For(typeof(StaticProxyFactory)); + + public override INHibernateProxy GetProxy(object id, ISessionImplementor session) + { + try + { + var cacheEntry = new ProxyCacheEntry(IsClassProxy ? PersistentClass : typeof(object), Interfaces); + var proxyActivator = Cache.GetOrAdd(cacheEntry, pke => CreateProxyActivator(pke)); + return proxyActivator( + new LiteLazyInitializer(EntityName, id, session, PersistentClass), + new NHibernateProxyFactoryInfo(EntityName, PersistentClass, Interfaces, GetIdentifierMethod, SetIdentifierMethod, ComponentIdType)); + } + catch (Exception ex) + { + Log.Error(ex, "Creating a proxy instance failed"); + throw new HibernateException("Creating a proxy instance failed", ex); + } + } + + Func CreateProxyActivator(ProxyCacheEntry pke) + { + var proxyBuilder = new NHibernateProxyBuilder(GetIdentifierMethod, SetIdentifierMethod, ComponentIdType, OverridesEquals); + var type = proxyBuilder.CreateProxyType(pke.BaseType, pke.Interfaces); + var ctor = type.GetConstructor(new[] {typeof(ILazyInitializer), typeof(NHibernateProxyFactoryInfo)}); + var li = Expression.Parameter(typeof(ILazyInitializer)); + var pf = Expression.Parameter(typeof(NHibernateProxyFactoryInfo)); + return Expression.Lambda>(Expression.New(ctor, li, pf), li, pf).Compile(); + } + + public override object GetFieldInterceptionProxy(object instanceToWrap) + { + var factory = new ProxyFactory(); + var interceptor = new DefaultDynamicLazyFieldInterceptor(); + return factory.CreateProxy(PersistentClass, interceptor, new[] { typeof(IFieldInterceptorAccessor) }); + } + } +} From 9cc5161b50232dbf3f71bef31459e6dd9dbc0787 Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Mon, 11 Dec 2017 09:24:30 +1300 Subject: [PATCH 2/7] Fix tests --- src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs b/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs index 8836eb6e84c..0a851f2652f 100644 --- a/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs +++ b/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs @@ -29,7 +29,7 @@ internal NHibernateProxyFactoryInfo(string entityName, System.Type persistentCla public IProxyFactory CreateProxyFactory() { - var factory = new DefaultProxyFactory(); + var factory = new StaticProxyFactory(); factory.PostInstantiate(_entityName, _persistentClass, new HashSet(_interfaces), _getIdentifierMethod, _setIdentifierMethod, _componentIdType); return factory; } From b4bfc90ae545c8d81c81cc01756f46b563ee14cd Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Mon, 11 Dec 2017 09:40:01 +1300 Subject: [PATCH 3/7] Fix comments --- src/NHibernate/Proxy/NHibernateProxyBuilder.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NHibernate/Proxy/NHibernateProxyBuilder.cs b/src/NHibernate/Proxy/NHibernateProxyBuilder.cs index 12935ed421f..da4b1e9181a 100644 --- a/src/NHibernate/Proxy/NHibernateProxyBuilder.cs +++ b/src/NHibernate/Proxy/NHibernateProxyBuilder.cs @@ -263,9 +263,9 @@ static void ImplementSetIdentifier(TypeBuilder typeBuilder, MethodInfo method) /* set { - ((INHibernateLazyInitializer)this).LazyInitializer.Initialize(); - ((INHibernateLazyInitializer)this).LazyInitializer.Identifier = value; - ((INHibernateLazyInitializer)this).LazyInitializer.GetImplementation(). = value; + ((INHibernateProxy)this).LazyInitializer.Initialize(); + ((INHibernateProxy)this).LazyInitializer.Identifier = value; + ((INHibernateProxy)this).LazyInitializer.GetImplementation(). = value; } */ var propertyType = method.GetParameters()[0].ParameterType; @@ -359,7 +359,7 @@ static void EmitCallMethod(MethodInfo method, ILGenerator IL, OpCode opCode) static void EmitCallImplementation(MethodInfo method, ILGenerator IL) { - //((INHibernateLazyInitializer)this).LazyInitializer.GetImplementation().(args..); + //((INHibernateProxy)this).LazyInitializer.GetImplementation().(args..); EmitGetLazyInitializer(IL); IL.Emit(OpCodes.Callvirt, LazyInitializerGetImplementationMethod); IL.Emit(OpCodes.Unbox_Any, method.DeclaringType); From bf8056860df7058c4adb999ca0aa0543cbd317fe Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Mon, 11 Dec 2017 12:45:51 +1300 Subject: [PATCH 4/7] Code cleanup --- .../Proxy/NHibernateProxyBuilder.cs | 161 +++++++++--------- 1 file changed, 78 insertions(+), 83 deletions(-) diff --git a/src/NHibernate/Proxy/NHibernateProxyBuilder.cs b/src/NHibernate/Proxy/NHibernateProxyBuilder.cs index da4b1e9181a..828044e4b66 100644 --- a/src/NHibernate/Proxy/NHibernateProxyBuilder.cs +++ b/src/NHibernate/Proxy/NHibernateProxyBuilder.cs @@ -16,14 +16,12 @@ class NHibernateProxyBuilder const MethodAttributes InterceptorMethodsAttributes = MethodAttributes.Private | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.NewSlot | MethodAttributes.Virtual; - const string HibernateLazyInitializerFieldName = nameof(INHibernateProxy.HibernateLazyInitializer); - const MethodAttributes constructorAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; static readonly System.Type NHibernateProxyType = typeof(INHibernateProxy); - static readonly PropertyInfo NHibernateProxyTypeLazyInitializerProperty = NHibernateProxyType.GetProperty(HibernateLazyInitializerFieldName); + static readonly PropertyInfo NHibernateProxyTypeLazyInitializerProperty = NHibernateProxyType.GetProperty(nameof(INHibernateProxy.HibernateLazyInitializer)); static readonly System.Type LazyInitializerType = typeof(ILazyInitializer); static readonly PropertyInfo LazyInitializerIdentifierProperty = LazyInitializerType.GetProperty(nameof(ILazyInitializer.Identifier)); static readonly MethodInfo LazyInitializerInitializeMethod = LazyInitializerType.GetMethod(nameof(ILazyInitializer.Initialize)); @@ -87,7 +85,7 @@ public TypeInfo CreateProxyType(System.Type baseType, IReadOnlyCollection return (ReturnType)((INHibernateProxy)this).LazyInitializer.Identifier; + // get => return (ReturnType)(this.__lazyInitializer.Identifier; var methodOverride = DefaultyProxyMethodBuilder.GenerateMethodSignature(method.Name, method, typeBuilder); var IL = methodOverride.GetILGenerator(); - EmitCallBaseIfLazyInitializerIsNull(method, IL); + EmitCallBaseIfLazyInitializerIsNull(IL, method, lazyInitializerField); - EmitGetLazyInitializer(IL); + 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); @@ -258,112 +255,110 @@ static void ImplementGetIdentifier(TypeBuilder typeBuilder, MethodInfo method) typeBuilder.DefineMethodOverride(methodOverride, method); } - static void ImplementSetIdentifier(TypeBuilder typeBuilder, MethodInfo method) + static void ImplementSetIdentifier(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) { /* set { - ((INHibernateProxy)this).LazyInitializer.Initialize(); - ((INHibernateProxy)this).LazyInitializer.Identifier = value; - ((INHibernateProxy)this).LazyInitializer.GetImplementation(). = value; + (this.__lazyInitializer.Initialize(); + (this.__lazyInitializer.Identifier = value; + (this.__lazyInitializer.GetImplementation(). = value; } */ var propertyType = method.GetParameters()[0].ParameterType; var methodOverride = DefaultyProxyMethodBuilder.GenerateMethodSignature(method.Name, method, typeBuilder); var IL = methodOverride.GetILGenerator(); - EmitCallBaseIfLazyInitializerIsNull(method, IL); + EmitCallBaseIfLazyInitializerIsNull(IL, method, lazyInitializerField); - EmitGetLazyInitializer(IL); + IL.Emit(OpCodes.Ldarg_0); + IL.Emit(OpCodes.Ldfld, lazyInitializerField); IL.Emit(OpCodes.Callvirt, LazyInitializerInitializeMethod); - EmitGetLazyInitializer(IL); + 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(method, IL); + EmitCallImplementation(IL, method, lazyInitializerField); IL.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodOverride, method); } - static void ImplementCallMethodOnEmbeddedComponentId(TypeBuilder typeBuilder, MethodInfo method) + static void ImplementCallMethodOnEmbeddedComponentId(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) { - // ((INHibernateProxy)this).LazyInitializer.Identifier.(args..); + // (this.__lazyInitializer.Identifier.(args..); var methodOverride = DefaultyProxyMethodBuilder.GenerateMethodSignature(method.Name, method, typeBuilder); var IL = methodOverride.GetILGenerator(); - EmitCallBaseIfLazyInitializerIsNull(method, IL); + EmitCallBaseIfLazyInitializerIsNull(IL, method, lazyInitializerField); - EmitGetLazyInitializer(IL); + IL.Emit(OpCodes.Ldarg_0); + IL.Emit(OpCodes.Ldfld, lazyInitializerField); IL.Emit(OpCodes.Callvirt, LazyInitializerIdentifierProperty.GetMethod); IL.Emit(OpCodes.Unbox_Any, method.DeclaringType); - EmitCallMethod(method, IL, OpCodes.Callvirt); + EmitCallMethod(IL, OpCodes.Callvirt, method); IL.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodOverride, method); } - static void ImplementCallMethodOnImplementation(TypeBuilder typeBuilder, MethodInfo method) + static void ImplementCallMethodOnImplementation(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) { /* - return ((INHibernateProxy)this).LazyInitializer.GetImplementation().(args..); + return (this.__lazyInitializer.GetImplementation().(args..); */ var methodOverride = DefaultyProxyMethodBuilder.GenerateMethodSignature(method.Name, method, typeBuilder); var IL = methodOverride.GetILGenerator(); - EmitCallBaseIfLazyInitializerIsNull(method, IL); + EmitCallBaseIfLazyInitializerIsNull(IL, method, lazyInitializerField); - EmitCallImplementation(method, IL); + EmitCallImplementation(IL, method, lazyInitializerField); IL.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodOverride, method); } - static void EmitCallBaseIfLazyInitializerIsNull(MethodInfo method, ILGenerator IL) + static void EmitCallBaseIfLazyInitializerIsNull(ILGenerator IL, MethodInfo method, FieldInfo lazyInitializerField) { - //if (((INHibernateProxy) this).LazyInitializer == null) - // return base..< Method > (args..) + //if ((this.__lazyInitializer == null) + // return base. (args..) - EmitGetLazyInitializer(IL); + IL.Emit(OpCodes.Ldarg_0); + IL.Emit(OpCodes.Ldfld, lazyInitializerField); var skipBaseCall = IL.DefineLabel(); IL.Emit(OpCodes.Ldnull); IL.Emit(OpCodes.Bne_Un, skipBaseCall); IL.Emit(OpCodes.Ldarg_0); - EmitCallMethod(method, IL, OpCodes.Call); + EmitCallMethod(IL, OpCodes.Call, method); IL.Emit(OpCodes.Ret); IL.MarkLabel(skipBaseCall); } - static void EmitGetLazyInitializer(ILGenerator IL) - { - IL.Emit(OpCodes.Ldarg_0); - IL.Emit(OpCodes.Castclass, NHibernateProxyType); - IL.Emit(OpCodes.Callvirt, NHibernateProxyTypeLazyInitializerProperty.GetMethod); - } - - static void EmitCallMethod(MethodInfo method, ILGenerator IL, OpCode opCode) + static void EmitCallMethod(ILGenerator IL, OpCode opCode, MethodInfo method) { for (var i = 0; i < method.GetParameters().Length; i++) IL.Emit(OpCodes.Ldarg_S, (sbyte) (1 + i)); IL.Emit(opCode, method); } - static void EmitCallImplementation(MethodInfo method, ILGenerator IL) + static void EmitCallImplementation(ILGenerator IL, MethodInfo method, FieldInfo lazyInitializerField) { - //((INHibernateProxy)this).LazyInitializer.GetImplementation().(args..); - EmitGetLazyInitializer(IL); + //(this.__lazyInitializer.GetImplementation().(args..); + IL.Emit(OpCodes.Ldarg_0); + IL.Emit(OpCodes.Ldfld, lazyInitializerField); IL.Emit(OpCodes.Callvirt, LazyInitializerGetImplementationMethod); IL.Emit(OpCodes.Unbox_Any, method.DeclaringType); - EmitCallMethod(method, IL, OpCodes.Callvirt); + EmitCallMethod(IL, OpCodes.Callvirt, method); } } } From 64e4b579ee4b9b365a2b3d0d95fa3496d5729f9b Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Mon, 11 Dec 2017 13:00:55 +1300 Subject: [PATCH 5/7] Fix comments --- .../Proxy/NHibernateProxyBuilder.cs | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/NHibernate/Proxy/NHibernateProxyBuilder.cs b/src/NHibernate/Proxy/NHibernateProxyBuilder.cs index 828044e4b66..bca6d0fd317 100644 --- a/src/NHibernate/Proxy/NHibernateProxyBuilder.cs +++ b/src/NHibernate/Proxy/NHibernateProxyBuilder.cs @@ -119,11 +119,11 @@ void CreateProxiedMethod(TypeBuilder typeBuilder, MethodInfo method, FieldInfo l } else if (!_overridesEquals && method.Name == "Equals" && method.GetBaseDefinition() == typeof(object).GetMethod("Equals", new[] {typeof(object)})) { -//skip + //skip } else if (!_overridesEquals && method.Name == "GetHashCode" && method.GetBaseDefinition() == typeof(object).GetMethod("GetHashCode")) { -//skip + //skip } else if (_componentIdType != null && _componentIdType.IsMethodOf(method)) { @@ -197,7 +197,7 @@ static void ImplementGetObjectData(TypeBuilder typeBuilder, FieldInfo proxyInfoF IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, proxyInfoField); - //this.LazyInitializer.Identifier + //this.__lazyInitializer.Identifier IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, lazyInitializerField); IL.Emit(OpCodes.Callvirt, LazyInitializerIdentifierProperty.GetMethod); @@ -229,7 +229,7 @@ static void ImplementGetLazyInitializer(TypeBuilder typeBuilder, MethodInfo meth var IL = getMethod.GetILGenerator(); // This is equivalent to: - // get { return __lazyInitializer; } + // get { return this.__lazyInitializer; } IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, lazyInitializerField); IL.Emit(OpCodes.Ret); @@ -239,7 +239,7 @@ static void ImplementGetLazyInitializer(TypeBuilder typeBuilder, MethodInfo meth static void ImplementGetIdentifier(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) { - // get => return (ReturnType)(this.__lazyInitializer.Identifier; + // get => return ()this.__lazyInitializer.Identifier; var methodOverride = DefaultyProxyMethodBuilder.GenerateMethodSignature(method.Name, method, typeBuilder); var IL = methodOverride.GetILGenerator(); @@ -260,9 +260,9 @@ static void ImplementSetIdentifier(TypeBuilder typeBuilder, MethodInfo method, F /* set { - (this.__lazyInitializer.Initialize(); - (this.__lazyInitializer.Identifier = value; - (this.__lazyInitializer.GetImplementation(). = value; + this.__lazyInitializer.Initialize(); + this.__lazyInitializer.Identifier = value; + this.__lazyInitializer.GetImplementation(). = value; } */ var propertyType = method.GetParameters()[0].ParameterType; @@ -291,7 +291,7 @@ static void ImplementSetIdentifier(TypeBuilder typeBuilder, MethodInfo method, F static void ImplementCallMethodOnEmbeddedComponentId(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) { - // (this.__lazyInitializer.Identifier.(args..); + //this.__lazyInitializer.Identifier.(args..); var methodOverride = DefaultyProxyMethodBuilder.GenerateMethodSignature(method.Name, method, typeBuilder); var IL = methodOverride.GetILGenerator(); @@ -310,9 +310,7 @@ static void ImplementCallMethodOnEmbeddedComponentId(TypeBuilder typeBuilder, Me static void ImplementCallMethodOnImplementation(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) { - /* - return (this.__lazyInitializer.GetImplementation().(args..); - */ + //return this.__lazyInitializer.GetImplementation().(args..); var methodOverride = DefaultyProxyMethodBuilder.GenerateMethodSignature(method.Name, method, typeBuilder); var IL = methodOverride.GetILGenerator(); @@ -327,7 +325,7 @@ static void ImplementCallMethodOnImplementation(TypeBuilder typeBuilder, MethodI static void EmitCallBaseIfLazyInitializerIsNull(ILGenerator IL, MethodInfo method, FieldInfo lazyInitializerField) { - //if ((this.__lazyInitializer == null) + //if (this.__lazyInitializer == null) // return base. (args..) IL.Emit(OpCodes.Ldarg_0); @@ -353,7 +351,7 @@ static void EmitCallMethod(ILGenerator IL, OpCode opCode, MethodInfo method) static void EmitCallImplementation(ILGenerator IL, MethodInfo method, FieldInfo lazyInitializerField) { - //(this.__lazyInitializer.GetImplementation().(args..); + //this.__lazyInitializer.GetImplementation().(args..); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, lazyInitializerField); IL.Emit(OpCodes.Callvirt, LazyInitializerGetImplementationMethod); From fa51673df2ba1db91a88b6063be6337188e43734 Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Wed, 13 Dec 2017 10:48:45 +1300 Subject: [PATCH 6/7] Code review fixes --- .../Proxy/DynamicProxy/ProxyFactory.cs | 10 +- src/NHibernate/Proxy/LiteLazyInitializer.cs | 2 +- .../Proxy/NHibernateProxyBuilder.cs | 124 +++++++++++------- .../Proxy/NHibernateProxyFactoryInfo.cs | 14 +- .../Proxy/NHibernateProxyObjectReference.cs | 6 +- src/NHibernate/Proxy/StaticProxyFactory.cs | 12 +- 6 files changed, 96 insertions(+), 72 deletions(-) diff --git a/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs b/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs index 675e34ba013..99cf1cbb53d 100644 --- a/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs +++ b/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs @@ -21,11 +21,11 @@ public sealed class ProxyFactory { internal static readonly ConcurrentDictionary _cache = new ConcurrentDictionary(); - internal static readonly ConstructorInfo defaultBaseConstructor = typeof(object).GetConstructor(new System.Type[0]); + private static readonly ConstructorInfo defaultBaseConstructor = typeof(object).GetConstructor(new System.Type[0]); private static readonly MethodInfo getValue = ReflectHelper.GetMethod( si => si.GetValue(null, null)); - internal static readonly MethodInfo setType = ReflectHelper.GetMethod( + private static readonly MethodInfo setType = ReflectHelper.GetMethod( si => si.SetType(null)); private static readonly MethodInfo addValue = ReflectHelper.GetMethod( si => si.AddValue(null, null)); @@ -139,7 +139,7 @@ internal static IEnumerable GetProxiableMethods(System.Type type, IE .Distinct(); } - internal static ConstructorBuilder DefineConstructor(TypeBuilder typeBuilder, System.Type parentType) + private static ConstructorBuilder DefineConstructor(TypeBuilder typeBuilder, System.Type parentType) { const MethodAttributes constructorAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | @@ -166,7 +166,7 @@ internal static ConstructorBuilder DefineConstructor(TypeBuilder typeBuilder, Sy return constructor; } - internal static void ImplementGetObjectData(System.Type baseType, IReadOnlyCollection baseInterfaces, TypeBuilder typeBuilder, FieldInfo interceptorField) + private static void ImplementGetObjectData(System.Type baseType, IReadOnlyCollection baseInterfaces, TypeBuilder typeBuilder, FieldInfo interceptorField) { const MethodAttributes attributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual; @@ -217,7 +217,7 @@ internal static void ImplementGetObjectData(System.Type baseType, IReadOnlyColle IL.Emit(OpCodes.Ret); } - internal static void DefineSerializationConstructor(TypeBuilder typeBuilder, FieldInfo interceptorField, ConstructorBuilder defaultConstructor) + private static void DefineSerializationConstructor(TypeBuilder typeBuilder, FieldInfo interceptorField, ConstructorBuilder defaultConstructor) { const MethodAttributes constructorAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | diff --git a/src/NHibernate/Proxy/LiteLazyInitializer.cs b/src/NHibernate/Proxy/LiteLazyInitializer.cs index c4340aeba1a..9684bbed5f7 100644 --- a/src/NHibernate/Proxy/LiteLazyInitializer.cs +++ b/src/NHibernate/Proxy/LiteLazyInitializer.cs @@ -4,7 +4,7 @@ namespace NHibernate.Proxy { [Serializable] - sealed class LiteLazyInitializer : AbstractLazyInitializer + internal sealed class LiteLazyInitializer : AbstractLazyInitializer { internal LiteLazyInitializer(string entityName, object id, ISessionImplementor session, System.Type persistentClass) : base(entityName, id, session) diff --git a/src/NHibernate/Proxy/NHibernateProxyBuilder.cs b/src/NHibernate/Proxy/NHibernateProxyBuilder.cs index bca6d0fd317..bd3613c725a 100644 --- a/src/NHibernate/Proxy/NHibernateProxyBuilder.cs +++ b/src/NHibernate/Proxy/NHibernateProxyBuilder.cs @@ -11,30 +11,30 @@ namespace NHibernate.Proxy { - class NHibernateProxyBuilder + internal class NHibernateProxyBuilder { - const MethodAttributes InterceptorMethodsAttributes = MethodAttributes.Private | MethodAttributes.Final | MethodAttributes.HideBySig | - MethodAttributes.SpecialName | MethodAttributes.NewSlot | MethodAttributes.Virtual; - - const MethodAttributes constructorAttributes = MethodAttributes.Public | - MethodAttributes.HideBySig | MethodAttributes.SpecialName | - MethodAttributes.RTSpecialName; - - static readonly System.Type NHibernateProxyType = typeof(INHibernateProxy); - static readonly PropertyInfo NHibernateProxyTypeLazyInitializerProperty = NHibernateProxyType.GetProperty(nameof(INHibernateProxy.HibernateLazyInitializer)); - static readonly System.Type LazyInitializerType = typeof(ILazyInitializer); - static readonly PropertyInfo LazyInitializerIdentifierProperty = LazyInitializerType.GetProperty(nameof(ILazyInitializer.Identifier)); - static readonly MethodInfo LazyInitializerInitializeMethod = LazyInitializerType.GetMethod(nameof(ILazyInitializer.Initialize)); - static readonly MethodInfo LazyInitializerGetImplementationMethod = LazyInitializerType.GetMethod(nameof(ILazyInitializer.GetImplementation), System.Type.EmptyTypes); - static readonly IProxyAssemblyBuilder ProxyAssemblyBuilder = new DefaultProxyAssemblyBuilder(); - - static readonly ConstructorInfo SecurityCriticalAttributeConstructor = typeof(SecurityCriticalAttribute).GetConstructor(System.Type.EmptyTypes); - static readonly MethodInfo SerializableGetObjectDataMethod = typeof(ISerializable).GetMethod(nameof(ISerializable.GetObjectData)); - - readonly MethodInfo _getIdentifierMethod; - readonly MethodInfo _setIdentifierMethod; - readonly IAbstractComponentType _componentIdType; - readonly bool _overridesEquals; + private const MethodAttributes constructorAttributes = + MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; + + private static readonly ConstructorInfo ObjectConstructor = typeof(object).GetConstructor(System.Type.EmptyTypes); + + private static readonly System.Type NHibernateProxyType = typeof(INHibernateProxy); + private static readonly PropertyInfo NHibernateProxyTypeLazyInitializerProperty = NHibernateProxyType.GetProperty(nameof(INHibernateProxy.HibernateLazyInitializer)); + private static readonly System.Type LazyInitializerType = typeof(ILazyInitializer); + private static readonly PropertyInfo LazyInitializerIdentifierProperty = LazyInitializerType.GetProperty(nameof(ILazyInitializer.Identifier)); + private static readonly MethodInfo LazyInitializerInitializeMethod = LazyInitializerType.GetMethod(nameof(ILazyInitializer.Initialize)); + private static readonly MethodInfo LazyInitializerGetImplementationMethod = LazyInitializerType.GetMethod(nameof(ILazyInitializer.GetImplementation), System.Type.EmptyTypes); + private static readonly IProxyAssemblyBuilder ProxyAssemblyBuilder = new DefaultProxyAssemblyBuilder(); + + private static readonly ConstructorInfo SecurityCriticalAttributeConstructor = typeof(SecurityCriticalAttribute).GetConstructor(System.Type.EmptyTypes); + private static readonly MethodInfo SerializableGetObjectDataMethod = typeof(ISerializable).GetMethod(nameof(ISerializable.GetObjectData)); + private static readonly MethodInfo SerializationInfoSetTypeMethod = ReflectHelper.GetMethod(si => si.SetType(null)); + + private readonly MethodInfo _getIdentifierMethod; + private readonly MethodInfo _setIdentifierMethod; + private readonly IAbstractComponentType _componentIdType; + private readonly bool _overridesEquals; + public NHibernateProxyBuilder(MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, IAbstractComponentType componentIdType, bool overridesEquals) { _getIdentifierMethod = getIdentifierMethod; @@ -103,7 +103,7 @@ public TypeInfo CreateProxyType(System.Type baseType, IReadOnlyCollection())); var IL = methodBuilder.GetILGenerator(); @@ -191,8 +195,9 @@ static void ImplementGetObjectData(TypeBuilder typeBuilder, FieldInfo proxyInfoF IL.Emit(OpCodes.Ldarg_1); IL.Emit(OpCodes.Ldtoken, typeof (NHibernateProxyObjectReference)); IL.Emit(OpCodes.Call, ReflectionCache.TypeMethods.GetTypeFromHandle); - IL.Emit(OpCodes.Callvirt, ProxyFactory.setType); + IL.Emit(OpCodes.Callvirt, SerializationInfoSetTypeMethod); + // (new NHibernateProxyObjectReference(this.__proxyInfo, this.__lazyInitializer.Identifier)).GetObjectData(info, context); //this.__proxyInfo IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, proxyInfoField); @@ -212,7 +217,6 @@ static void ImplementGetObjectData(TypeBuilder typeBuilder, FieldInfo proxyInfoF IL.Emit(OpCodes.Ldarg_1); IL.Emit(OpCodes.Ldarg_2); - IL.Emit(OpCodes.Callvirt, SerializableGetObjectDataMethod); IL.Emit(OpCodes.Ret); @@ -220,16 +224,19 @@ static void ImplementGetObjectData(TypeBuilder typeBuilder, FieldInfo proxyInfoF typeBuilder.DefineMethodOverride(methodBuilder, SerializableGetObjectDataMethod); } - static void ImplementGetLazyInitializer(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) + private static void ImplementGetLazyInitializer(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) { - // Implement the getter - var getMethod = typeBuilder.DefineMethod($"{NHibernateProxyType.FullName}.get_{nameof(INHibernateProxy.HibernateLazyInitializer)}", InterceptorMethodsAttributes, CallingConventions.HasThis, LazyInitializerType, System.Type.EmptyTypes); + // get { return this.__lazyInitializer; } + + const MethodAttributes attributes = + MethodAttributes.Private | MethodAttributes.Final | MethodAttributes.HideBySig | + MethodAttributes.SpecialName | MethodAttributes.NewSlot | MethodAttributes.Virtual; + + var getMethod = typeBuilder.DefineMethod($"{NHibernateProxyType.FullName}.get_{nameof(INHibernateProxy.HibernateLazyInitializer)}", attributes, CallingConventions.HasThis, LazyInitializerType, System.Type.EmptyTypes); getMethod.SetImplementationFlags(MethodImplAttributes.Managed | MethodImplAttributes.IL); var IL = getMethod.GetILGenerator(); - // This is equivalent to: - // get { return this.__lazyInitializer; } IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, lazyInitializerField); IL.Emit(OpCodes.Ret); @@ -237,9 +244,16 @@ static void ImplementGetLazyInitializer(TypeBuilder typeBuilder, MethodInfo meth typeBuilder.DefineMethodOverride(getMethod, method); } - static void ImplementGetIdentifier(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) + private static void ImplementGetIdentifier(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) { - // get => return ()this.__lazyInitializer.Identifier; + /* + get + { + if (this.__lazyInitializer == null) + return base.get_(); + return ()this.__lazyInitializer.Identifier; + } + */ var methodOverride = DefaultyProxyMethodBuilder.GenerateMethodSignature(method.Name, method, typeBuilder); var IL = methodOverride.GetILGenerator(); @@ -255,11 +269,13 @@ static void ImplementGetIdentifier(TypeBuilder typeBuilder, MethodInfo method, F typeBuilder.DefineMethodOverride(methodOverride, method); } - static void ImplementSetIdentifier(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) + private static void ImplementSetIdentifier(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) { /* set { + if (this.__lazyInitializer == null) + return base.set_(value); this.__lazyInitializer.Initialize(); this.__lazyInitializer.Identifier = value; this.__lazyInitializer.GetImplementation(). = value; @@ -289,9 +305,13 @@ static void ImplementSetIdentifier(TypeBuilder typeBuilder, MethodInfo method, F typeBuilder.DefineMethodOverride(methodOverride, method); } - static void ImplementCallMethodOnEmbeddedComponentId(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) + private static void ImplementCallMethodOnEmbeddedComponentId(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) { - //this.__lazyInitializer.Identifier.(args..); + /* + if (this.__lazyInitializer == null) + return base.(args..); + this.__lazyInitializer.Identifier.(args..); + */ var methodOverride = DefaultyProxyMethodBuilder.GenerateMethodSignature(method.Name, method, typeBuilder); var IL = methodOverride.GetILGenerator(); @@ -308,9 +328,13 @@ static void ImplementCallMethodOnEmbeddedComponentId(TypeBuilder typeBuilder, Me typeBuilder.DefineMethodOverride(methodOverride, method); } - static void ImplementCallMethodOnImplementation(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) + private static void ImplementCallMethodOnImplementation(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField) { - //return this.__lazyInitializer.GetImplementation().(args..); + /* + if (this.__lazyInitializer == null) + return base.(args..); + return this.__lazyInitializer.GetImplementation().(args..) + */ var methodOverride = DefaultyProxyMethodBuilder.GenerateMethodSignature(method.Name, method, typeBuilder); var IL = methodOverride.GetILGenerator(); @@ -323,10 +347,10 @@ static void ImplementCallMethodOnImplementation(TypeBuilder typeBuilder, MethodI typeBuilder.DefineMethodOverride(methodOverride, method); } - static void EmitCallBaseIfLazyInitializerIsNull(ILGenerator IL, MethodInfo method, FieldInfo lazyInitializerField) + private static void EmitCallBaseIfLazyInitializerIsNull(ILGenerator IL, MethodInfo method, FieldInfo lazyInitializerField) { //if (this.__lazyInitializer == null) - // return base. (args..) + // return base.(args..) IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, lazyInitializerField); @@ -342,16 +366,16 @@ static void EmitCallBaseIfLazyInitializerIsNull(ILGenerator IL, MethodInfo metho IL.MarkLabel(skipBaseCall); } - static void EmitCallMethod(ILGenerator IL, OpCode opCode, MethodInfo method) + private static void EmitCallMethod(ILGenerator IL, OpCode opCode, MethodInfo method) { for (var i = 0; i < method.GetParameters().Length; i++) IL.Emit(OpCodes.Ldarg_S, (sbyte) (1 + i)); IL.Emit(opCode, method); } - static void EmitCallImplementation(ILGenerator IL, MethodInfo method, FieldInfo lazyInitializerField) + private static void EmitCallImplementation(ILGenerator IL, MethodInfo method, FieldInfo lazyInitializerField) { - //this.__lazyInitializer.GetImplementation().(args..); + //(()this.__lazyInitializer.GetImplementation()).(args..); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, lazyInitializerField); IL.Emit(OpCodes.Callvirt, LazyInitializerGetImplementationMethod); diff --git a/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs b/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs index 0a851f2652f..065c3705729 100644 --- a/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs +++ b/src/NHibernate/Proxy/NHibernateProxyFactoryInfo.cs @@ -10,12 +10,12 @@ namespace NHibernate.Proxy [Serializable] public sealed class NHibernateProxyFactoryInfo : ISerializable { - readonly string _entityName; - readonly System.Type _persistentClass; - readonly System.Type[] _interfaces; - readonly MethodInfo _getIdentifierMethod; - readonly MethodInfo _setIdentifierMethod; - readonly IAbstractComponentType _componentIdType; + private readonly string _entityName; + private readonly System.Type _persistentClass; + private readonly System.Type[] _interfaces; + private readonly MethodInfo _getIdentifierMethod; + private readonly MethodInfo _setIdentifierMethod; + private readonly IAbstractComponentType _componentIdType; internal NHibernateProxyFactoryInfo(string entityName, System.Type persistentClass, System.Type[] interfaces, MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod, IAbstractComponentType componentIdType) { @@ -34,7 +34,7 @@ public IProxyFactory CreateProxyFactory() return factory; } - NHibernateProxyFactoryInfo(SerializationInfo info, StreamingContext context) + private NHibernateProxyFactoryInfo(SerializationInfo info, StreamingContext context) { _entityName = (string) info.GetValue(nameof(_entityName), typeof(string)); _persistentClass = (System.Type) info.GetValue(nameof(_persistentClass), typeof(System.Type)); diff --git a/src/NHibernate/Proxy/NHibernateProxyObjectReference.cs b/src/NHibernate/Proxy/NHibernateProxyObjectReference.cs index 2cc8e3a3354..9878bc5bc21 100644 --- a/src/NHibernate/Proxy/NHibernateProxyObjectReference.cs +++ b/src/NHibernate/Proxy/NHibernateProxyObjectReference.cs @@ -7,8 +7,8 @@ namespace NHibernate.Proxy [Serializable] public sealed class NHibernateProxyObjectReference : IObjectReference, ISerializable { - readonly NHibernateProxyFactoryInfo _proxyFactoryInfo; - readonly object _identifier; + private readonly NHibernateProxyFactoryInfo _proxyFactoryInfo; + private readonly object _identifier; public NHibernateProxyObjectReference(NHibernateProxyFactoryInfo proxyFactoryInfo, object identifier) { @@ -16,7 +16,7 @@ public NHibernateProxyObjectReference(NHibernateProxyFactoryInfo proxyFactoryInf _identifier = identifier; } - NHibernateProxyObjectReference(SerializationInfo info, StreamingContext context) + private NHibernateProxyObjectReference(SerializationInfo info, StreamingContext context) { _proxyFactoryInfo = (NHibernateProxyFactoryInfo) info.GetValue(nameof(_proxyFactoryInfo), typeof(NHibernateProxyFactoryInfo)); _identifier = info.GetValue(nameof(_identifier), typeof(object)); diff --git a/src/NHibernate/Proxy/StaticProxyFactory.cs b/src/NHibernate/Proxy/StaticProxyFactory.cs index 264f2098730..d053a93abd2 100644 --- a/src/NHibernate/Proxy/StaticProxyFactory.cs +++ b/src/NHibernate/Proxy/StaticProxyFactory.cs @@ -9,10 +9,10 @@ namespace NHibernate.Proxy { public sealed class StaticProxyFactory : AbstractProxyFactory { - static readonly ConcurrentDictionary> Cache = - new ConcurrentDictionary>(); + private static readonly ConcurrentDictionary> + Cache = new ConcurrentDictionary>(); - static readonly INHibernateLogger Log = NHibernateLogger.For(typeof(StaticProxyFactory)); + private static readonly INHibernateLogger Log = NHibernateLogger.For(typeof(StaticProxyFactory)); public override INHibernateProxy GetProxy(object id, ISessionImplementor session) { @@ -31,8 +31,8 @@ public override INHibernateProxy GetProxy(object id, ISessionImplementor session } } - Func CreateProxyActivator(ProxyCacheEntry pke) - { + private Func CreateProxyActivator(ProxyCacheEntry pke) + { var proxyBuilder = new NHibernateProxyBuilder(GetIdentifierMethod, SetIdentifierMethod, ComponentIdType, OverridesEquals); var type = proxyBuilder.CreateProxyType(pke.BaseType, pke.Interfaces); var ctor = type.GetConstructor(new[] {typeof(ILazyInitializer), typeof(NHibernateProxyFactoryInfo)}); @@ -45,7 +45,7 @@ public override object GetFieldInterceptionProxy(object instanceToWrap) { var factory = new ProxyFactory(); var interceptor = new DefaultDynamicLazyFieldInterceptor(); - return factory.CreateProxy(PersistentClass, interceptor, new[] { typeof(IFieldInterceptorAccessor) }); + return factory.CreateProxy(PersistentClass, interceptor, typeof(IFieldInterceptorAccessor)); } } } From 01ed70012932324fa1f869a04259e8d89c39e609 Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Wed, 13 Dec 2017 10:54:10 +1300 Subject: [PATCH 7/7] Mark another method as private --- src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs b/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs index 99cf1cbb53d..a40adbb80bc 100644 --- a/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs +++ b/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs @@ -254,7 +254,7 @@ private static void DefineSerializationConstructor(TypeBuilder typeBuilder, Fiel IL.Emit(OpCodes.Ret); } - internal static void AddSerializationSupport(System.Type baseType, IReadOnlyCollection baseInterfaces, TypeBuilder typeBuilder, FieldInfo interceptorField, ConstructorBuilder defaultConstructor) + private static void AddSerializationSupport(System.Type baseType, IReadOnlyCollection baseInterfaces, TypeBuilder typeBuilder, FieldInfo interceptorField, ConstructorBuilder defaultConstructor) { ConstructorInfo serializableConstructor = typeof(SerializableAttribute).GetConstructor(new System.Type[0]); var customAttributeBuilder = new CustomAttributeBuilder(serializableConstructor, new object[0]);