comparison Extensions/JointureAddOn/Emit/DynamicCompilationSpike.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f990fcb411a9
1 using System;
2 using System.Reflection;
3 using System.Reflection.Emit;
4
5 namespace BLToolkit.Emit
6 {
7 public delegate object GetHandler(object source);
8
9 public delegate void SetHandler(object source, object value);
10
11 public delegate object InstantiateObjectHandler();
12
13 public static class DynamicMethodCompiler
14 {
15 // DynamicMethodCompiler
16
17 // CreateInstantiateObjectDelegate
18 internal static InstantiateObjectHandler CreateInstantiateObjectHandler(Type type)
19 {
20 ConstructorInfo constructorInfo =
21 type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null,
22 new Type[0], null);
23 if (constructorInfo == null)
24 {
25 throw new ApplicationException(
26 string.Format(
27 "The type {0} must declare an empty constructor (the constructor may be private, internal, protected, protected internal, or public).",
28 type));
29 }
30
31 var dynamicMethod = new DynamicMethod("InstantiateObject", MethodAttributes.Static | MethodAttributes.Public,
32 CallingConventions.Standard, typeof(object), null, type, true);
33 ILGenerator generator = dynamicMethod.GetILGenerator();
34 generator.Emit(OpCodes.Newobj, constructorInfo);
35 generator.Emit(OpCodes.Ret);
36 return (InstantiateObjectHandler)dynamicMethod.CreateDelegate(typeof(InstantiateObjectHandler));
37 }
38
39 // CreateGetDelegate
40 internal static GetHandler CreateGetHandler(Type type, PropertyInfo propertyInfo)
41 {
42 MethodInfo getMethodInfo = propertyInfo.GetGetMethod(true);
43 DynamicMethod dynamicGet = CreateGetDynamicMethod(type);
44 ILGenerator getGenerator = dynamicGet.GetILGenerator();
45
46 getGenerator.Emit(OpCodes.Ldarg_0);
47 getGenerator.Emit(OpCodes.Call, getMethodInfo);
48 BoxIfNeeded(getMethodInfo.ReturnType, getGenerator);
49 getGenerator.Emit(OpCodes.Ret);
50
51 return (GetHandler)dynamicGet.CreateDelegate(typeof(GetHandler));
52 }
53
54 // CreateGetDelegate
55 internal static GetHandler CreateGetHandler(Type type, FieldInfo fieldInfo)
56 {
57 DynamicMethod dynamicGet = CreateGetDynamicMethod(type);
58 ILGenerator getGenerator = dynamicGet.GetILGenerator();
59
60 getGenerator.Emit(OpCodes.Ldarg_0);
61 getGenerator.Emit(OpCodes.Ldfld, fieldInfo);
62 BoxIfNeeded(fieldInfo.FieldType, getGenerator);
63 getGenerator.Emit(OpCodes.Ret);
64
65 return (GetHandler)dynamicGet.CreateDelegate(typeof(GetHandler));
66 }
67
68 // CreateSetDelegate
69 internal static SetHandler CreateSetHandler(Type type, PropertyInfo propertyInfo)
70 {
71 MethodInfo setMethodInfo = propertyInfo.GetSetMethod(true);
72 DynamicMethod dynamicSet = CreateSetDynamicMethod(type);
73 ILGenerator setGenerator = dynamicSet.GetILGenerator();
74
75 setGenerator.Emit(OpCodes.Ldarg_0);
76 setGenerator.Emit(OpCodes.Ldarg_1);
77 UnboxIfNeeded(setMethodInfo.GetParameters()[0].ParameterType, setGenerator);
78 setGenerator.Emit(OpCodes.Call, setMethodInfo);
79 setGenerator.Emit(OpCodes.Ret);
80
81 return (SetHandler)dynamicSet.CreateDelegate(typeof(SetHandler));
82 }
83
84 // CreateSetDelegate
85 internal static SetHandler CreateSetHandler(Type type, FieldInfo fieldInfo)
86 {
87 DynamicMethod dynamicSet = CreateSetDynamicMethod(type);
88 ILGenerator setGenerator = dynamicSet.GetILGenerator();
89
90 setGenerator.Emit(OpCodes.Ldarg_0);
91 setGenerator.Emit(OpCodes.Ldarg_1);
92 UnboxIfNeeded(fieldInfo.FieldType, setGenerator);
93 setGenerator.Emit(OpCodes.Stfld, fieldInfo);
94 setGenerator.Emit(OpCodes.Ret);
95
96 return (SetHandler)dynamicSet.CreateDelegate(typeof(SetHandler));
97 }
98
99 // CreateGetDynamicMethod
100 private static DynamicMethod CreateGetDynamicMethod(Type type)
101 {
102 return new DynamicMethod("DynamicGet", typeof(object), new[] { typeof(object) }, type, true);
103 }
104
105 // CreateSetDynamicMethod
106 private static DynamicMethod CreateSetDynamicMethod(Type type)
107 {
108 return new DynamicMethod("DynamicSet", typeof(void), new[] { typeof(object), typeof(object) }, type, true);
109 }
110
111 // BoxIfNeeded
112 private static void BoxIfNeeded(Type type, ILGenerator generator)
113 {
114 if (type.IsValueType)
115 {
116 generator.Emit(OpCodes.Box, type);
117 }
118 }
119
120 // UnboxIfNeeded
121 private static void UnboxIfNeeded(Type type, ILGenerator generator)
122 {
123 if (type.IsValueType)
124 {
125 generator.Emit(OpCodes.Unbox_Any, type);
126 }
127 }
128 }
129 }