纯手工打造Emit实现AOP 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); } }
2023-02-21 00:41:39 33KB C# Emit AOP
1
适用于Visual Studio 2017的μC/ OS-II 修改自Micrium官网适应给VS2017源码,加入卢有亮的《嵌入式实时操作系统μC/ OS原理与实践》移植代码中的实验示例。 包含的MICRIUM产品版本 uC / OS-II v2.92.13 uC / OS-III v3.06.02 uC / CPU v1.31.01 uC / LIB v1.38.02 IDE环境要求 Visual Studio v2017版 VS解决方案文件路径 Microsoft / Windows /内核/OS2/VS/OS2.sln Microsoft / Windows /内核/OS3/VS/OS3.sln 使用说明 在Visual Studio:上方路径的文件 在项目上点快捷,清理已编译的文件 修改Windows SDK Version为可用的版本, 10.0.17134.0 编译并
2023-02-20 22:24:59 648KB 系统开源
1
阿尔泰公司数据采集卡usb2811驱动程序和示例程序源代码
2023-02-20 15:59:14 4.34MB 数据采集卡 驱动程序 源代码
1
WebSocket示例 该项目是通过引导的。 服务器 该服务器是使用FastAPI实现的。 首先,安装依赖项: pip install fastapi "uvicorn[standard]" 然后,运行它: uvicorn run:app 必须在localhost:8000中创建服务器。 客户 客户端使用React和Recharts实现。 转到前端目录: cd frontend 安装依赖项: yarn install 并运行它: yarn start 在localhost:3000打开浏览器,您必须看到每秒更新一次的图表。
2023-02-19 19:21:42 202KB JavaScript
1
码头工人= :red_heart: 该存储库的目标是提供大量示例,说明如何将与PostgreSQL,Nginx,Elasticsearch等不同软件产品一起使用。示例包含在开发和配置过程中本地使用的版本。 为了使用这些示例,建议至少安装19.03.5版本的19.03.5 。 一些示例包含Vagrant文​​件,该文件为安装了所需版本docker的您简化了虚拟机的创建。 如果Dockerfile,某些软件的docker-compose.yml文件丢失,您只需要打开拉取请求就可以了,我会尽快添加它们。 我有大量用于不同项目的原始示例,但没有足够的时间来使它们足够清楚以适合此存储库。 我非常热衷于帮助其他工程师解
2023-02-19 14:24:37 2.09MB mysql docker redis dockerfile
1
P2P(点对点)的流行产生了大批网络传输软件,这里我们要介绍的就是自己写一个简单的P2P文件传输,一方发送文件,一方接受,直到传输完整个文件。
2023-02-19 12:52:04 797KB Delphi 2010 indy 10.5.5
1
Java8并行流 Java 8并行流示例
2023-02-19 09:21:09 175KB Java
1
matlab 文件名批量命名示例
2023-02-18 23:17:37 90B matlab 文件名命名
1
android studio 使用NDK和swig编译c++示例。使用swig可以自动化编译c++函数。比较方便。http://blog.csdn.net/qq_16064871
2023-02-18 18:26:08 10.41MB swig ndk
1
本篇文章主要介绍了Android DataBinding的官方双向绑定示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
2023-02-18 16:53:46 69KB Android DataBinding Android 双向绑定
1