读书人

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

发布时间: 2012-03-24 14:00:46 作者: rapoo

【分享】纯手工打造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);            }        }


[解决办法]
好吧,我学习下
[解决办法]
感谢分享。
------解决方案--------------------


建议推荐下,引起关注。

说实话,你若发布一个什么 datagrid 无敌分页万能绑定版估计受关注程度会很高。


[解决办法]
呵呵,愈来愈看不懂了
[解决办法]
要是你能够把我200W的分页数据分页的效率和分2W数据的效率一样,我就十分感谢你了。
友情UP!!!
[解决办法]
呵呵,改天写个无敌分页万能绑定版
[解决办法]
虽然不懂 但还是多谢分享了
[解决办法]
推荐 Orchard
[解决办法]
好人啊。顶你。但我看不懂。
[解决办法]
谢谢楼主分享,既然有源码,应该可以推荐一下。
[解决办法]
好贴!收藏。
[解决办法]

探讨
呵呵,多谢楼上2位友情顶贴

话说上次贴的一些Emit的代码,貌似大家都没啥子兴趣

这次直接附上了源码,不知这次情况如何,拭目以待。。。

[解决办法]
谢谢楼主的分享
[解决办法]
Emit确实难搞,但是搞通了确实很牛.
Emit命名空间可以说是为系统提供了一个最大程度上的灵活性实现.
[解决办法]

[解决办法]
你会写ASP吗
[解决办法]
下载 分享
[解决办法]
看看

支持原创

[解决办法]
aop是什么?
[解决办法]
感谢分享
[解决办法]
谢谢楼主的分享
[解决办法]
谢谢楼主 关注了慢慢看
[解决办法]
好牌。。。。。。。
[解决办法]
探讨
好牌。。。。。。。

[解决办法]
探讨
引用:
好牌。。。。。。。

[解决办法]
能描述下思路吗?
[解决办法]
Emit
[解决办法]
汗,昵称就不能改么,就真的不能改么,就真的真的不能改么?
[解决办法]
谢谢分享,学习了!!!
[解决办法]
对源码有特别的兴趣
[解决办法]
谢谢分享
[解决办法]
好好学学,楼主辛苦了
[解决办法]
谢谢分享
------解决方案--------------------


不懂,不过源码拿回去看看,哈哈。。多谢楼主分享
[解决办法]
学习学习,谢谢LZ了!!
[解决办法]
学习学习,谢谢LZ了!!
[解决办法]
学习!!
[解决办法]
无知了,不知道emit是啥
[解决办法]
学习 学习
[解决办法]
谢谢分享
[解决办法]
不错啊真的不错啊啊啊啊

[解决办法]
楼主犀利
[解决办法]
不懂 学习学习 谢谢楼主分享
[解决办法]

探讨

引用:
能描述下思路吗?


大致的思路就是使用Emit动态生成一个类,继承当前的类,重写当前类中所有的虚方法

重写的过程遵循以下6步:

1.初始化上下文环境

2.调用切面中的BeforeInvoke方法

3.在调用基类的方法

4.调用切面中的AfterInvoke方法

5.返回调用基类的结果

6.结束

[解决办法]
学习。。。。
[解决办法]
不错不错
[解决办法]
4352345234523
[解决办法]
2345234523
[解决办法]
嗯,上次看过楼主发的Emit的代码,确实挺不错的,也为那个帖子如此冷清替楼主感到可惜
[解决办法]
不明白干什么的,学习中,楼主解释
[解决办法]
shuoshihua hanbudong
[解决办法]
好东西~
[解决办法]
东西不错,学习学习
谢谢分享
[解决办法]
嗯 好东西 。。。
[解决办法]
好吧,我学习下
[解决办法]

星然看不懂,也要顶一下
[解决办法]
非常给了。。。谢谢了 、、、、、、呵呵
[解决办法]
楼主,我BSD开源形式的能拿走集成到我的一个项目中吗?
[解决办法]
学习 学习
[解决办法]
顶一下..................
[解决办法]
学习!
[解决办法]
AOP具体的原理我就不多讲了,大家可以查查资料,我这里用的【继承+重写+动态植入IL代码】

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

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

[解决办法]
楼主厉害啊~!
[解决办法]
强,顶~!
------解决方案--------------------


厉害啊
[解决办法]
来看看,谢谢分享
[解决办法]
谢谢分享,学习了!!!
[解决办法]
顶一个
[解决办法]
好牛啊,顶一个!
[解决办法]
wwwaassa
[解决办法]

探讨
非常给了。。。谢谢了 、、、、、、呵呵

[解决办法]
多谢楼主分享
[解决办法]
学习一下吧
[解决办法]
学习中....
[解决办法]
谢谢楼主 接分了 哈
[解决办法]
其实写出来了,就很不错了,大家现在不太关注,以后总会关注的
[解决办法]
赞赏分享精神,努力学习ing
[解决办法]
看来我也得弄点小东西学习一下
[解决办法]
看不懂...帮顶
[解决办法]
最近才接触到Emit,请问楼主这方面有什么好的学习资料么?
[解决办法]
看不懂啊!
[解决办法]
ding
[解决办法]
喜欢Emit
[解决办法]
学习一下。
[解决办法]
非常感谢楼主!
[解决办法]
好,不错,就是我看不懂

读书人网 >asp.net

热点推荐