当前位置: 代码迷 >> ASP.NET >> 纯手工打造Emit,实现AOP,附源码下载
  详细解决方案

纯手工打造Emit,实现AOP,附源码下载

热度:9517   发布时间:2013-02-26 00:00:00.0
【分享】纯手工打造Emit,实现AOP,附源码下载
比较喜欢Emit,所以就胡乱写点东西。这个是新鲜出炉的,分享给大家

AOP具体的原理我就不多讲了,大家可以查查资料,我这里用的【继承+重写+动态植入IL代码】

好了,废话少说,下载地址如下

http://download.csdn.net/source/3441835

在附上一个代码片段,嘿嘿。欢迎大虾拍砖

C# code
private static void OverrideMethods(TypeBuilder tb, MethodInfo method)        {            if (!method.IsPublic|| !method.IsVirtual || IsObjectMethod(method)) return;            Type[] paramTypes = GetParameterTypes(method);            MethodAttributes attr = MethodAttributes.Public | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.Virtual;            MethodBuilder mb = tb.DefineMethod(method.Name, attr, method.ReturnType, paramTypes);            LocalBuilder result = null;            ILGenerator il = mb.GetILGenerator();            bool is_void = method.ReturnType != typeof(void);            if (is_void == false)                result = il.DeclareLocal(method.ReturnType);            object[] attrs = method.GetCustomAttributes(typeof(AspectAttribute), false);            if (attrs != null)            {                //初始化所有当前方法用到的参数object[]                CreateLocalParameterArr(il, paramTypes);                //初始化AspectContext                Type ctxType = typeof(AspectContext);                ConstructorInfo info = ctxType.GetConstructor(Type.EmptyTypes);                var ctx = il.DeclareLocal(ctxType);                il.Emit(OpCodes.Newobj, info);                il.Emit(OpCodes.Stloc, ctx);                //给AspectContext的参数值属性ParameterArgs赋值                var propMethod = ctxType.GetMethod("set_ParameterArgs");                il.Emit(OpCodes.Ldloc, ctx);                il.Emit(OpCodes.Ldloc_0);                il.Emit(OpCodes.Call, propMethod);                int m = attrs.Length;                LocalBuilder[] lbs = new LocalBuilder[m];                MethodInfo[] endInvokeMethods = new MethodInfo[m];                //初始化标记的横切对象,并调用横切对象的BeforeInvoke方法                for (int i = 0; i < m; i++)                {                    var tmpType = attrs[i].GetType();                    var aspect = il.DeclareLocal(tmpType);                    ConstructorInfo tmpInfo = tmpType.GetConstructor(Type.EmptyTypes);                    il.Emit(OpCodes.Newobj, tmpInfo);                    il.Emit(OpCodes.Stloc, aspect);                    var before_invoke_method = tmpType.GetMethod("BeforeInvoke");                    endInvokeMethods[i] = tmpType.GetMethod("AfterInvoke");                    il.Emit(OpCodes.Ldloc, aspect);                    il.Emit(OpCodes.Ldloc, ctx);                    il.Emit(OpCodes.Callvirt, before_invoke_method);                    il.Emit(OpCodes.Nop);                    lbs[i] = aspect;                }                //类对象,参数值依次入栈                for (int i = 0; i <= paramTypes.Length; i++)                    il.Emit(OpCodes.Ldarg, i);                //调用基类的方法                il.Emit(OpCodes.Call, method);                //如果有返回值,保存返回值到局部变量                if (is_void == false)                    il.Emit(OpCodes.Stloc, result);                //调用横切对象的AfterInvoke方法                for (int i = 0; i < m; i++)                {                    il.Emit(OpCodes.Ldloc, lbs[i]);                    il.Emit(OpCodes.Ldloc, ctx);                    il.Emit(OpCodes.Callvirt, endInvokeMethods[i]);                    il.Emit(OpCodes.Nop);                }                //如果有返回值,则把返回值压栈                if (is_void == false)                    il.Emit(OpCodes.Ldloc, result);                //返回                il.Emit(OpCodes.Ret);            }        }


------解决方案--------------------------------------------------------
好吧,我学习下
------解决方案--------------------------------------------------------
感谢分享。
------解决方案--------------------------------------------------------
  相关解决方案