7
7
#endregion
8
8
9
9
using System ;
10
- using System . Collections . Generic ;
11
- using System . Diagnostics ;
12
- using System . Linq ;
13
10
using System . Reflection ;
14
11
using System . Reflection . Emit ;
15
12
16
13
namespace NHibernate . Proxy . DynamicProxy
17
14
{
18
- internal class DefaultyProxyMethodBuilder : IProxyMethodBuilder
15
+ class DefaultyProxyMethodBuilder : IProxyMethodBuilder
19
16
{
20
17
public DefaultyProxyMethodBuilder ( ) : this ( new DefaultMethodEmitter ( ) ) { }
21
18
22
19
public DefaultyProxyMethodBuilder ( IMethodBodyEmitter emitter )
23
20
{
24
- if ( emitter == null )
25
- {
26
- throw new ArgumentNullException ( "emitter" ) ;
27
- }
28
- MethodBodyEmitter = emitter ;
21
+ MethodBodyEmitter = emitter ?? throw new ArgumentNullException ( nameof ( emitter ) ) ;
29
22
}
30
23
31
- public IMethodBodyEmitter MethodBodyEmitter { get ; private set ; }
24
+ public IMethodBodyEmitter MethodBodyEmitter { get ; }
32
25
33
- private static MethodBuilder GenerateMethodSignature ( string name , MethodInfo method , TypeBuilder typeBuilder )
26
+ public virtual void CreateProxiedMethod ( FieldInfo field , MethodInfo method , TypeBuilder typeBuilder )
34
27
{
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 ) ;
142
30
143
31
MethodBodyEmitter . EmitMethodBody ( proxyMethod , callbackMethod , method , field ) ;
144
32
145
33
typeBuilder . DefineMethodOverride ( proxyMethod , method ) ;
146
34
}
147
35
}
148
- }
36
+ }
0 commit comments