Skip to content

Commit f7d93a2

Browse files
committed
Implement generation of static proxy for INHibernateProxy
1 parent 5822c8e commit f7d93a2

12 files changed

+416
-231
lines changed

src/NHibernate/Bytecode/Lightweight/ReflectionOptimizer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ protected DynamicMethod CreateDynamicMethod(System.Type returnType, System.Type[
107107
return new DynamicMethod(string.Empty, returnType, argumentTypes, owner, canSkipChecks);
108108
}
109109

110-
private static void EmitCastToReference(ILGenerator il, System.Type type)
110+
internal static void EmitCastToReference(ILGenerator il, System.Type type)
111111
{
112112
if (type.IsValueType)
113113
{

src/NHibernate/Proxy/DefaultLazyInitializer.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
namespace NHibernate.Proxy
1010
{
11+
//Since v5.1
12+
[Obsolete("This class is not used anymore and will be removed in a future version. Please implement your version of ILazyInitializer")]
1113
[Serializable]
1214
public class DefaultLazyInitializer : BasicLazyInitializer, DynamicProxy.IInterceptor
1315
{
@@ -39,4 +41,4 @@ public object Intercept(InvocationInfo info)
3941
return returnValue;
4042
}
4143
}
42-
}
44+
}
Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Linq;
23
using NHibernate.Engine;
34
using NHibernate.Intercept;
45
using NHibernate.Proxy.DynamicProxy;
@@ -7,20 +8,20 @@ namespace NHibernate.Proxy
78
{
89
public class DefaultProxyFactory : AbstractProxyFactory
910
{
10-
private readonly ProxyFactory factory = new ProxyFactory();
11+
1112
protected static readonly IInternalLogger log = LoggerProvider.LoggerFor(typeof (DefaultProxyFactory));
1213

1314
public override INHibernateProxy GetProxy(object id, ISessionImplementor session)
1415
{
16+
var factory = new ProxyFactory(new NHibernateProxyMethodBuilder(GetIdentifierMethod, SetIdentifierMethod, ComponentIdType, OverridesEquals));
1517
try
1618
{
17-
var initializer = new DefaultLazyInitializer(EntityName, PersistentClass, id, GetIdentifierMethod, SetIdentifierMethod, ComponentIdType, session, OverridesEquals);
18-
19-
object proxyInstance = IsClassProxy
20-
? factory.CreateProxy(PersistentClass, initializer, Interfaces)
21-
: factory.CreateProxy(typeof(object), initializer, Interfaces);
19+
var proxyType = factory.CreateProxyType(IsClassProxy ? PersistentClass : typeof(object), Interfaces);
2220

23-
return (INHibernateProxy) proxyInstance;
21+
var result = Activator.CreateInstance(proxyType);
22+
var proxy = (IProxy) result;
23+
proxy.Interceptor = new LiteLazyInitializer(EntityName, id, session, PersistentClass);
24+
return (INHibernateProxy) result;
2425
}
2526
catch (Exception ex)
2627
{
@@ -31,8 +32,12 @@ public override INHibernateProxy GetProxy(object id, ISessionImplementor session
3132

3233
public override object GetFieldInterceptionProxy(object instanceToWrap)
3334
{
34-
var interceptor = new DefaultDynamicLazyFieldInterceptor();
35-
return factory.CreateProxy(PersistentClass, interceptor, new[] { typeof(IFieldInterceptorAccessor) });
35+
var factory = new ProxyFactory();
36+
var proxyType = factory.CreateProxyType(PersistentClass, typeof(IFieldInterceptorAccessor));
37+
var result = Activator.CreateInstance(proxyType);
38+
var proxy = (IProxy) result;
39+
proxy.Interceptor = new DefaultDynamicLazyFieldInterceptor();
40+
return result;
3641
}
3742
}
3843
}

src/NHibernate/Proxy/DynamicProxy/DefaultProxyMethodBuilder.cs

Lines changed: 7 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -7,142 +7,30 @@
77
#endregion
88

99
using System;
10-
using System.Collections.Generic;
11-
using System.Diagnostics;
12-
using System.Linq;
1310
using System.Reflection;
1411
using System.Reflection.Emit;
1512

1613
namespace NHibernate.Proxy.DynamicProxy
1714
{
18-
internal class DefaultyProxyMethodBuilder : IProxyMethodBuilder
15+
class DefaultyProxyMethodBuilder : IProxyMethodBuilder
1916
{
2017
public DefaultyProxyMethodBuilder() : this(new DefaultMethodEmitter()) { }
2118

2219
public DefaultyProxyMethodBuilder(IMethodBodyEmitter emitter)
2320
{
24-
if (emitter == null)
25-
{
26-
throw new ArgumentNullException("emitter");
27-
}
28-
MethodBodyEmitter = emitter;
21+
MethodBodyEmitter = emitter ?? throw new ArgumentNullException(nameof(emitter));
2922
}
3023

31-
public IMethodBodyEmitter MethodBodyEmitter { get; private set; }
24+
public IMethodBodyEmitter MethodBodyEmitter { get; }
3225

33-
private static MethodBuilder GenerateMethodSignature(string name, MethodInfo method, TypeBuilder typeBuilder)
26+
public virtual void CreateProxiedMethod(FieldInfo field, MethodInfo method, TypeBuilder typeBuilder)
3427
{
35-
//TODO: Should we use attributes of base method?
36-
var methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual;
37-
38-
if (method.IsSpecialName)
39-
methodAttributes |= MethodAttributes.SpecialName;
40-
41-
ParameterInfo[] parameters = method.GetParameters();
42-
43-
MethodBuilder methodBuilder = typeBuilder.DefineMethod(name,
44-
methodAttributes,
45-
CallingConventions.HasThis,
46-
method.ReturnType,
47-
parameters.Select(param => param.ParameterType).ToArray());
48-
49-
System.Type[] typeArgs = method.GetGenericArguments();
50-
51-
if (typeArgs.Length > 0)
52-
{
53-
var typeNames = GenerateTypeNames(typeArgs.Length);
54-
var typeArgBuilders = methodBuilder.DefineGenericParameters(typeNames);
55-
56-
for (int index = 0; index < typeArgs.Length; index++)
57-
{
58-
// Copy generic parameter attributes (Covariant, Contravariant, ReferenceTypeConstraint,
59-
// NotNullableValueTypeConstraint, DefaultConstructorConstraint).
60-
var typeArgBuilder = typeArgBuilders[index];
61-
var typeArg = typeArgs[index];
62-
63-
typeArgBuilder.SetGenericParameterAttributes(typeArg.GenericParameterAttributes);
64-
65-
// Copy generic parameter constraints (class and interfaces).
66-
var typeConstraints = typeArg.GetGenericParameterConstraints()
67-
.Select(x => ResolveTypeConstraint(method, x))
68-
.ToArray();
69-
70-
var baseTypeConstraint = typeConstraints.SingleOrDefault(x => x.IsClass);
71-
typeArgBuilder.SetBaseTypeConstraint(baseTypeConstraint);
72-
73-
var interfaceTypeConstraints = typeConstraints.Where(x => !x.IsClass).ToArray();
74-
typeArgBuilder.SetInterfaceConstraints(interfaceTypeConstraints);
75-
}
76-
}
77-
return methodBuilder;
78-
}
79-
80-
private static System.Type ResolveTypeConstraint(MethodInfo method, System.Type typeConstraint)
81-
{
82-
if (typeConstraint != null && typeConstraint.IsGenericType)
83-
{
84-
var declaringType = method.DeclaringType;
85-
if (declaringType != null && declaringType.IsGenericType)
86-
{
87-
return BuildTypeConstraint(typeConstraint, declaringType);
88-
}
89-
}
90-
91-
return typeConstraint;
92-
}
93-
94-
private static System.Type BuildTypeConstraint(System.Type typeConstraint, System.Type declaringType)
95-
{
96-
var constraintGenericArguments = typeConstraint.GetGenericArguments();
97-
var declaringTypeGenericArguments = declaringType.GetGenericArguments();
98-
99-
var parametersMap = declaringType
100-
.GetGenericTypeDefinition()
101-
.GetGenericArguments()
102-
.ToDictionary(x => x, x => declaringTypeGenericArguments[x.GenericParameterPosition]);
103-
104-
var args = new System.Type[constraintGenericArguments.Length];
105-
var make = false;
106-
for (int index = 0; index < constraintGenericArguments.Length; index++)
107-
{
108-
var genericArgument = constraintGenericArguments[index];
109-
System.Type result;
110-
if (parametersMap.TryGetValue(genericArgument, out result))
111-
{
112-
make = true;
113-
}
114-
else
115-
{
116-
result = genericArgument;
117-
}
118-
args[index] = result;
119-
}
120-
if (make)
121-
{
122-
return typeConstraint.GetGenericTypeDefinition().MakeGenericType(args);
123-
}
124-
125-
return typeConstraint;
126-
}
127-
128-
private static string[] GenerateTypeNames(int count)
129-
{
130-
var result = new string[count];
131-
for (int index = 0; index < count; index++)
132-
{
133-
result[index] = string.Format("T{0}", index);
134-
}
135-
return result;
136-
}
137-
138-
public void CreateProxiedMethod(FieldInfo field, MethodInfo method, TypeBuilder typeBuilder)
139-
{
140-
var callbackMethod = GenerateMethodSignature(method.Name + "_callback", method, typeBuilder);
141-
var proxyMethod = GenerateMethodSignature(method.Name, method, typeBuilder);
28+
var callbackMethod = ProxyMethodBuilderHelper.GenerateMethodSignature(method.Name + "_callback", method, typeBuilder);
29+
var proxyMethod = ProxyMethodBuilderHelper.GenerateMethodSignature(method.Name, method, typeBuilder);
14230

14331
MethodBodyEmitter.EmitMethodBody(proxyMethod, callbackMethod, method, field);
14432

14533
typeBuilder.DefineMethodOverride(proxyMethod, method);
14634
}
14735
}
148-
}
36+
}

src/NHibernate/Proxy/DynamicProxy/IProxyCache.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace NHibernate.Proxy.DynamicProxy
1313
{
14+
[Obsolete]
1415
public interface IProxyCache
1516
{
1617
bool Contains(System.Type baseType, params System.Type[] baseInterfaces);
@@ -20,4 +21,4 @@ public interface IProxyCache
2021

2122
void StoreProxyType(TypeInfo result, System.Type baseType, params System.Type[] baseInterfaces);
2223
}
23-
}
24+
}

src/NHibernate/Proxy/DynamicProxy/NHibernateProxyImplementor.cs

Lines changed: 0 additions & 38 deletions
This file was deleted.

0 commit comments

Comments
 (0)