在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
1 using System.Reflection; 2 using System.Reflection.Emit; 3 public static class DefaultProxyBuilder 4 { 5 private static readonly Type VoidType = Type.GetType("System.Void"); //函数返回 void类型 6 7 public static T CreateProxy<T>() 8 { 9 Type classType = typeof(T); 10 11 string name = classType.Namespace + ".Aop"; //新的命名空间 12 string fileName = name + ".dll"; 13 14 15 var assemblyName = new AssemblyName(name); 16 var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName,AssemblyBuilderAccess.RunAndSave); 17 var moduleBuilder = assemblyBuilder.DefineDynamicModule(name, fileName);//构建命名空间 18 var aopType = BulidType(classType, moduleBuilder); 19 20 assemblyBuilder.Save(fileName); 21 return (T)Activator.CreateInstance(aopType); 22 } 23 24 private static Type BulidType(Type classType, ModuleBuilder moduleBuilder) 25 { 26 string className = classType.Name + "_Proxy"; 27 28 //定义类型 29 var typeBuilder = moduleBuilder.DefineType(className, 30 TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Class, 31 classType);//定义一个新类,继承classType 32 //定义字段 _inspector 声明一个私有且只读的变量 33 var inspectorFieldBuilder = typeBuilder.DefineField("_inspector", typeof(IInterceptor), 34 FieldAttributes.Private | FieldAttributes.InitOnly); 35 //构造函数 36 BuildCtor(classType, inspectorFieldBuilder, typeBuilder); 37 38 //构造方法 39 BuildMethod(classType, inspectorFieldBuilder, typeBuilder); 40 Type aopType = typeBuilder.CreateType(); 41 return aopType; 42 } 43 44 private static void BuildMethod(Type classType, FieldBuilder inspectorFieldBuilder, TypeBuilder typeBuilder) 45 { 46 var methodInfos = classType.GetMethods();//获取 原类型 47 foreach (var methodInfo in methodInfos)// 获取 虚函数 或 抽象函数 48 { 49 if (!methodInfo.IsVirtual && !methodInfo.IsAbstract) 50 continue; 51 if (methodInfo.Name == "ToString") 52 continue; 53 if (methodInfo.Name == "GetHashCode") 54 continue; 55 if (methodInfo.Name == "Equals") 56 continue; 57 58 var parameterInfos = methodInfo.GetParameters(); 59 var parameterTypes = parameterInfos.Select(p => p.ParameterType).ToArray(); 60 var parameterLength = parameterTypes.Length; 61 var hasResult = methodInfo.ReturnType != VoidType; 62 63 var methodBuilder = typeBuilder.DefineMethod(methodInfo.Name, 64 MethodAttributes.Public | MethodAttributes.Final | 65 MethodAttributes.Virtual 66 , methodInfo.ReturnType 67 , parameterTypes); 68 69 var il = methodBuilder.GetILGenerator(); 70 71 //局部变量 声明 72 il.DeclareLocal(typeof(object)); //correlationState (emit 标签从0 开始:loc_0,loc_1,loc_2) 73 il.DeclareLocal(typeof(object)); //result 74 il.DeclareLocal(typeof(object[])); //parameters 75 76 #region BeforeCall 77 //BeforeCall(string operationName, object[] inputs); 78 il.Emit(OpCodes.Ldarg_0); 79 80 il.Emit(OpCodes.Ldfld, inspectorFieldBuilder);//获取字段_inspector 81 il.Emit(OpCodes.Ldstr, methodInfo.Name);//参数operationName 82 83 if (parameterLength == 0)//判断方法参数长度 84 { 85 il.Emit(OpCodes.Ldnull);//null -> 参数 inputs 86 } 87 else 88 { 89 //创建new object[parameterLength]; 90 il.Emit(OpCodes.Ldc_I4, parameterLength); 91 il.Emit(OpCodes.Newarr, typeof(Object)); 92 il.Emit(OpCodes.Stloc_2);//压入局部变量2 parameters 93 94 for (int i = 0, j = 1; i < parameterLength; i++, j++) 95 { 96 //object[i] = arg[j] 97 il.Emit(OpCodes.Ldloc_2); 98 il.Emit(OpCodes.Ldc_I4, 0); 99 il.Emit(OpCodes.Ldarg, j); 100 if (parameterTypes[i].IsValueType) 101 il.Emit(OpCodes.Box, parameterTypes[i]);//对值类型装箱 102 il.Emit(OpCodes.Stelem_Ref); 103 } 104 il.Emit(OpCodes.Ldloc_2);//取出局部变量2 parameters-> 参数 inputs 105 } 106 107 il.Emit(OpCodes.Callvirt, typeof(IInterceptor).GetMethod("BeforeCall"));//调用BeforeCall 108 il.Emit(OpCodes.Stloc_0);//建返回压入局部变量0 correlationState 109 #endregion 110 111 #region base.Call 112 //Call methodInfo 113 il.Emit(OpCodes.Ldarg_0); // arg_0: 114 //获取参数表 115 for (int i = 1, length = parameterLength + 1; i < length; i++) 116 { 117 il.Emit(OpCodes.Ldarg_S, i); 118 } 119 il.Emit(OpCodes.Call, methodInfo); 120 //将返回值压入 局部变量1result void就压入null 121 if (!hasResult) 122 il.Emit(OpCodes.Ldnull); 123 else if (methodInfo.ReturnType.IsValueType) 124 il.Emit(OpCodes.Box, methodInfo.ReturnType);//对值类型装箱 125 il.Emit(OpCodes.Stloc_1); //返回值 保存到 result 126 #endregion 127 128 #region AfterCall 129 //AfterCall(string operationName, object returnValue, object correlationState); 130 il.Emit(OpCodes.Ldarg_0); 131 il.Emit(OpCodes.Ldfld, inspectorFieldBuilder);//获取字段_inspector 132 il.Emit(OpCodes.Ldstr, methodInfo.Name);//参数 operationName 133 il.Emit(OpCodes.Ldloc_1);//局部变量1 result 134 il.Emit(OpCodes.Ldloc_0);// 局部变量0 correlationState 135 il.Emit(OpCodes.Callvirt, typeof(IInterceptor).GetMethod("AfterCall")); 136 #endregion 137 138 #region result 139 //result 返回结果: void类型 直接返回函数,否则... 140 if (!hasResult) 141 { 142 il.Emit(OpCodes.Ret); 143 return; 144 } 145 il.Emit(OpCodes.Ldloc_1);//非void取出局部变量1 result 146 if (methodInfo.ReturnType.IsValueType) 147 il.Emit(OpCodes.Unbox_Any, methodInfo.ReturnType);//对值类型拆箱 148 il.Emit(OpCodes.Ret); 149 #endregion 150 } 151 } 152 153 private static void BuildCtor(Type classType, FieldBuilder inspectorFieldBuilder, TypeBuilder typeBuilder) 154 { 155 { //定义 代理类的 构造器 156 var ctorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, 157 Type.EmptyTypes); 158 var il = ctorBuilder.GetILGenerator(); 159 160 il.Emit(OpCodes.Ldarg_0); 161 il.Emit(OpCodes.Call, classType.GetConstructor(Type.EmptyTypes));//调用base的默认ctor 162 il.Emit(OpCodes.Ldarg_0); 163 //将typeof(classType)压入计算堆 164 il.Emit(OpCodes.Ldtoken, classType); 165 il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) })); 166 //调用DefaultInterceptorFactory.Create(type) 167 il.Emit(OpCodes.Call, typeof(DefaultInterceptorFactory).GetMethod("Create", new[] { typeof(Type) })); 168 //将结果保存到字段_inspector 169 il.Emit(OpCodes.Stfld, inspectorFieldBuilder); 170 il.Emit(OpCodes.Ret); 171 } 172 } 173 } 注:http://www.189works.com/article-43203-1.html |
请发表评论