private void BuildMethod(MethodInfo methodInfo, bool IsGloab) { string methodName = methodInfo.Name; ParameterInfo[] parameterInfos = methodInfo.GetParameters(); Type returnType = methodInfo.ReturnType; MethodBuilder methodBuilder = null; methodBuilder = _typeBuilder.DefineMethod(methodName, MethodAttributes.Public | MethodAttributes.Virtual, returnType, parameterInfos.Select(pi => pi.ParameterType).ToArray()); var il = methodBuilder.GetILGenerator(); Label castPerSuccess = il.DefineLabel(); Label castArroundSuccess = il.DefineLabel(); Label castAfterArroundSuccess = il.DefineLabel(); Label castPostSuccess = il.DefineLabel(); Label castExSuccess = il.DefineLabel(); #region Decalre InvokeContext Type contextType = typeof(InvokeContext); var contextLocal = il.DeclareLocal(contextType); il.Emit(OpCodes.Newobj, contextType.GetConstructor(Type.EmptyTypes)); il.Emit(OpCodes.Stloc, contextLocal); // set method name il.Emit(OpCodes.Ldloc, contextLocal); il.Emit(OpCodes.Ldstr, methodName); il.Emit(OpCodes.Call, contextType.GetMethod("SetMethod", BindingFlags.Public | BindingFlags.Instance)); #endregion #region Decalre result LocalBuilder resultLocal = null; if (returnType != typeof(void)) { resultLocal = il.DeclareLocal(returnType); if (returnType.IsValueType) { il.Emit(OpCodes.Ldstr, returnType.FullName); il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetType", new Type[] { typeof(string) })); il.Emit(OpCodes.Call, typeof(Activator).GetMethod("CreateInstance", new Type[] { typeof(Type) })); } else { il.Emit(OpCodes.Ldnull); } il.Emit(OpCodes.Stloc, resultLocal); } #endregion #region Declare Exception var exceptionLocal = il.DeclareLocal(typeof(Exception)); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Stloc, exceptionLocal); #endregion #region Invoke PreInvoke #region Set parameter to InvkeContext for (int i = 1; i <= parameterInfos.Length; i++) { il.Emit(OpCodes.Ldloc, contextLocal); il.Emit(OpCodes.Ldarg, i); if (parameterInfos[i - 1].ParameterType.IsValueType) { il.Emit(OpCodes.Box, parameterInfos[i - 1].ParameterType); } il.Emit(OpCodes.Call, contextType.GetMethod("SetParameter", BindingFlags.Public | BindingFlags.Instance)); } #endregion //var classInfoLocal1 = _realProxyType.GetType(); //ArroundAttribute preAspectLocal1 = // (ArroundAttribute)Attribute.GetCustomAttribute(classInfoLocal1, typeof(ArroundAttribute)); /* * C# 代码 * MethodInfo classInfoLocal = _realProxyField.GetType().GetMethod("methodName"); * ArroundAttribute preAspectLocal = * (ArroundAttribute)Attribute.GetCustomAttribute(classInfoLocal, typeof(ArroundAttribute)) * * if (preAspectLocal != null) * { * preAspectLocal.Action(contextLocal); * } * */ var classInfoLocal = il.DeclareLocal(_realProxyField.GetType()); LocalBuilder arrountAspectLocal = il.DeclareLocal(typeof(ArroundAttribute)); if (IsGloab) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, _realProxyField); il.Emit(OpCodes.Callvirt, typeof(System.Object).GetMethod("GetType", BindingFlags.Public | BindingFlags.Instance)); //il.Emit(OpCodes.Ldstr, methodName); //il.Emit(OpCodes.Callvirt, // typeof(System.Type).GetMethod("GetMethod", new Type[] { typeof(string) })); il.Emit(OpCodes.Stloc, classInfoLocal); il.Emit(OpCodes.Ldloc, classInfoLocal); } else { classInfoLocal = il.DeclareLocal(typeof(MethodInfo)); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, _realProxyField); il.Emit(OpCodes.Callvirt, typeof(System.Object).GetMethod("GetType", BindingFlags.Public | BindingFlags.Instance)); il.Emit(OpCodes.Ldstr, methodName); il.Emit(OpCodes.Callvirt, typeof(System.Type).GetMethod("GetMethod", new Type[] { typeof(string) })); il.Emit(OpCodes.Stloc, classInfoLocal); il.Emit(OpCodes.Ldloc, classInfoLocal); } il.Emit(OpCodes.Ldtoken, typeof(ArroundAttribute)); //generator.Emit(OpCodes.Ldloca, ) il.Emit(OpCodes.Call, typeof(System.Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(System.RuntimeTypeHandle) })); il.Emit(OpCodes.Call, typeof(System.Attribute).GetMethod("GetCustomAttribute", new Type[] { typeof(System.Reflection.MemberInfo), typeof(System.Type) })); il.Emit(OpCodes.Castclass, typeof(ArroundAttribute)); il.Emit(OpCodes.Stloc, arrountAspectLocal); il.Emit(OpCodes.Ldloc, arrountAspectLocal); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brtrue_S, castArroundSuccess); il.Emit(OpCodes.Ldloc, arrountAspectLocal); il.Emit(OpCodes.Ldloc, contextLocal); il.Emit(OpCodes.Callvirt, typeof(ArroundAttribute).GetMethod("BeginAction", new Type[] { typeof(InvokeContext) })); il.MarkLabel(castArroundSuccess); #endregion #region pre var preAspectLocal = il.DeclareLocal(typeof(PostAspectAttribute)); /* * generator.Emit(OpCodes.Ldarg_0); * generator.Emit(OpCodes.Ldfld, _realProxyField); * generator.Emit(OpCodes.Callvirt, typeof(System.Object).GetMethod("GetType", BindingFlags.Public | BindingFlags.Instance)); * generator.Emit(OpCodes.Ldstr, methodName); * generator.Emit(OpCodes.Callvirt, * typeof(System.Type).GetMethod("GetMethod", new Type[] { typeof(string) })); * generator.Emit(OpCodes.Stloc, classInfoLocal); */ il.Emit(OpCodes.Ldloc, classInfoLocal); il.Emit(OpCodes.Ldtoken, typeof(PreAspectAttribute)); //generator.Emit(OpCodes.Ldloca, ) il.Emit(OpCodes.Call, typeof(System.Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(System.RuntimeTypeHandle) })); il.Emit(OpCodes.Call, typeof(System.Attribute).GetMethod("GetCustomAttribute", new Type[] { typeof(System.Reflection.MethodInfo), typeof(System.Type) })); il.Emit(OpCodes.Castclass, typeof(PreAspectAttribute)); il.Emit(OpCodes.Stloc, preAspectLocal); il.Emit(OpCodes.Ldloc, preAspectLocal); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brtrue_S, castPerSuccess); il.Emit(OpCodes.Ldloc, preAspectLocal); il.Emit(OpCodes.Ldloc, contextLocal); il.Emit(OpCodes.Callvirt, typeof(AspectAttribute).GetMethod("Action", new Type[] { typeof(InvokeContext) })); il.MarkLabel(castPerSuccess); #endregion #region Begin Exception Block Label exLbl = il.BeginExceptionBlock(); #endregion #region Invoke il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, _realProxyField); for (int i = 1; i <= parameterInfos.Length; i++) { il.Emit(OpCodes.Ldarg, i); } il.Emit(OpCodes.Call, _realProxyType.GetMethod(methodName, BindingFlags.Public | BindingFlags.Instance)); if (typeof(void) != returnType) { il.Emit(OpCodes.Stloc, resultLocal); } #endregion #region Invoke PostInovke #region Set result to InvkeContext il.Emit(OpCodes.Ldloc, contextLocal); // load parameter if (typeof(void) != returnType) { il.Emit(OpCodes.Ldloc, resultLocal); if (returnType.IsValueType) { il.Emit(OpCodes.Box, returnType); } } else { il.Emit(OpCodes.Ldnull); } il.Emit(OpCodes.Call, contextType.GetMethod("SetResult", BindingFlags.Public | BindingFlags.Instance)); #endregion #region Invoke PostInovke #region Set result to InvkeContext il.Emit(OpCodes.Ldloc, contextLocal); // load parameter if (typeof(void) != returnType) { il.Emit(OpCodes.Ldloc, resultLocal); if (returnType.IsValueType) { il.Emit(OpCodes.Box, returnType); } } else { il.Emit(OpCodes.Ldnull); } il.Emit(OpCodes.Call, contextType.GetMethod("SetResult", BindingFlags.Public | BindingFlags.Instance)); #endregion /* * C# 代码 * MethodInfo classInfoLocal = _realProxyField.GetType().GetMethod("methodName"); * PostAspectAttribute postAspectLocal = * (PostAspectAttribute)Attribute.GetCustomAttribute(classInfoLocal, typeof(PostAspectAttribute)) * * if (postAspectLocal != null) * { * postAspectLocal.Action(contextLocal); * } * */ // get post aspect if has //var classInfoLocal = generator.DeclareLocal(typeof(System.Reflection.MethodInfo)); var postAspectLocal = il.DeclareLocal(typeof(PostAspectAttribute)); /* * generator.Emit(OpCodes.Ldarg_0); * generator.Emit(OpCodes.Ldfld, _realProxyField); * generator.Emit(OpCodes.Callvirt, typeof(System.Object).GetMethod("GetType", BindingFlags.Public | BindingFlags.Instance)); * generator.Emit(OpCodes.Ldstr, methodName); * generator.Emit(OpCodes.Callvirt, * typeof(System.Type).GetMethod("GetMethod", new Type[] { typeof(string) })); * generator.Emit(OpCodes.Stloc, classInfoLocal); */ il.Emit(OpCodes.Ldloc, classInfoLocal); il.Emit(OpCodes.Ldtoken, typeof(PostAspectAttribute)); //generator.Emit(OpCodes.Ldloca, ) il.Emit(OpCodes.Call, typeof(System.Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(System.RuntimeTypeHandle) })); il.Emit(OpCodes.Call, typeof(System.Attribute).GetMethod("GetCustomAttribute", new Type[] { typeof(System.Reflection.MethodInfo), typeof(System.Type) })); il.Emit(OpCodes.Castclass, typeof(PostAspectAttribute)); il.Emit(OpCodes.Stloc, postAspectLocal); il.Emit(OpCodes.Ldloc, postAspectLocal); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brtrue_S, castPostSuccess); il.Emit(OpCodes.Ldloc, postAspectLocal); il.Emit(OpCodes.Ldloc, contextLocal); il.Emit(OpCodes.Callvirt, typeof(AspectAttribute).GetMethod("Action", new Type[] { typeof(InvokeContext) })); il.MarkLabel(castPostSuccess); #endregion /* * C# 代码 * MethodInfo classInfoLocal = _realProxyField.GetType().GetMethod("methodName"); * ArroundAttribute postAspectLocal = * (ArroundAttribute)Attribute.GetCustomAttribute(classInfoLocal, typeof(ArroundAttribute)) * * if (postAspectLocal != null) * { * postAspectLocal.Action(contextLocal); * } * */ il.Emit(OpCodes.Ldloc, arrountAspectLocal); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brtrue_S, castAfterArroundSuccess); il.Emit(OpCodes.Ldloc, arrountAspectLocal); il.Emit(OpCodes.Ldloc, contextLocal); il.Emit(OpCodes.Callvirt, typeof(ArroundAttribute).GetMethod("EndAction", new Type[] { typeof(InvokeContext) })); il.MarkLabel(castAfterArroundSuccess); #endregion #region Catch Block il.BeginCatchBlock(typeof(Exception)); il.Emit(OpCodes.Stloc, exceptionLocal); il.Emit(OpCodes.Ldloc, contextLocal); il.Emit(OpCodes.Ldloc, exceptionLocal); il.Emit(OpCodes.Call, contextType.GetMethod("SetError", BindingFlags.Public | BindingFlags.Instance)); /* * C# 代码 * MethodInfo classInfoLocal = _realProxyField.GetType().GetMethod("methodName"); * ExceptionAspectAttribute exAspectLocal = * (ExceptionAspectAttribute)Attribute.GetCustomAttribute(classInfoLocal, typeof(ExceptionAspectAttribute)) * * if (exAspectLocal != null) * { * exAspectLocal.Action(contextLocal); * } * */ // get exception aspect if has //var classInfoLocal = generator.DeclareLocal(typeof(System.Reflection.MethodInfo)); var exAspectLocal = il.DeclareLocal(typeof(ArroundAttribute)); /* * il.Emit(OpCodes.Ldarg_0); * il.Emit(OpCodes.Ldfld, _realProxyField); * il.Emit(OpCodes.Callvirt, typeof(System.Object).GetMethod("GetType", BindingFlags.Public | BindingFlags.Instance)); * il.Emit(OpCodes.Ldstr, methodName); * il.Emit(OpCodes.Callvirt, * typeof(System.Type).GetMethod("GetMethod", new Type[] { typeof(string) })); * il.Emit(OpCodes.Stloc, classInfoLocal); */ il.Emit(OpCodes.Ldloc, classInfoLocal); il.Emit(OpCodes.Ldtoken, typeof(ExceptionAspectAttribute)); //generator.Emit(OpCodes.Ldloca, ) il.Emit(OpCodes.Call, typeof(System.Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(System.RuntimeTypeHandle) })); il.Emit(OpCodes.Call, typeof(System.Attribute).GetMethod("GetCustomAttribute", new Type[] { typeof(System.Reflection.MethodInfo), typeof(System.Type) })); il.Emit(OpCodes.Castclass, typeof(ExceptionAspectAttribute)); il.Emit(OpCodes.Stloc, exAspectLocal); il.Emit(OpCodes.Ldloc, exAspectLocal); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brtrue_S, castExSuccess); il.Emit(OpCodes.Ldloc, exAspectLocal); il.Emit(OpCodes.Ldloc, contextLocal); il.Emit(OpCodes.Callvirt, typeof(AspectAttribute).GetMethod("Action", new Type[] { typeof(InvokeContext) })); il.MarkLabel(castExSuccess); #endregion #region End Exception Block il.EndExceptionBlock(); #endregion if (typeof(void) != returnType) { il.Emit(OpCodes.Ldloc, resultLocal); } il.Emit(OpCodes.Ret); }