77#endregion
88
99using System ;
10- using System . Collections . Generic ;
11- using System . Diagnostics ;
12- using System . Linq ;
1310using System . Reflection ;
1411using System . Reflection . Emit ;
1512
1613namespace 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+ }
0 commit comments