C# 使用Emit实现动态AOP框架 (二)
程序员文章站
2022-07-10 23:52:50
实现DynamicProxy前,先介绍几个必要的辅助类: 一、切面上下文类AspectContext 该类是作为切面特性类的OnEntry和OnEixt方法的参数用的,该类包含了被代理对象Sender、当前切入的方法名称(Name)、调用方法的参数列表(Args)以及返回值(Result) 二、切面 ......
实现dynamicproxy前,先介绍几个必要的辅助类:
一、切面上下文类aspectcontext
该类是作为切面特性类的onentry和oneixt方法的参数用的,该类包含了被代理对象sender、当前切入的方法名称(name)、调用方法的参数列表(args)以及返回值(result)
1 public class aspectcontext 2 { 3 4 #region 构造函数 5 /// <summary> 6 /// 构造函数 7 /// </summary> 8 /// <param name="sender">被切入的对象</param> 9 /// <param name="name">切入方法名称</param> 10 /// <param name="args">调用参数</param> 11 public aspectcontext(object sender, string name, object[] args) 12 { 13 sender = sender; name = name; args = args; result = null; 14 } 15 #endregion 16 17 #region 属性 18 19 /// <summary> 20 /// 被切入的对象 21 /// </summary> 22 public object sender { get; set; } 23 24 /// <summary> 25 ///切入方法名称 26 /// </summary> 27 public string name { get; set; } 28 29 /// <summary> 30 /// 方法调用参数 31 /// </summary> 32 public object[] args { get; set; } 33 34 /// <summary> 35 /// 返回值 36 /// </summary> 37 public object result { get; set; } 38 39 #endregion 40 }
二、切面特性基类 aspectattribute
/// <summary> /// 切面特性基类 /// </summary> [attributeusage(attributetargets.class | attributetargets.constructor | attributetargets.method | attributetargets.property)] public abstract class aspectattribute : attribute { public aspectattribute() { interceptype = xaop.interceptype.all; } public abstract intercepttype intercepttype { get; set; } public abstract void onentry(aspectcontext context); public abstract void onexit(aspectcontext context); }
该类作为所有切面特性的基类,包含拦截的类型、方法调用入口和方法调用出口。
三、拦截类型 intercepttype
/// <summary> /// 拦截类型 /// </summary> public enum intercepttype { #region 枚举值 /// <summary> /// 入口 /// </summary> onentry = 1, /// <summary> /// 出口 /// </summary> onexit = 2, /// <summary> /// 所有 /// </summary> all = 3 #endregion }
四、日志特性类
该类简单实现了方法调用前后的日志记录功能。
/// <summary> /// 日志特性 /// </summary> public class logattribute : aspectattribute { public override intercepttype intercepttype { get; set; } #region 开始调用 /// <summary> /// 开始调用 /// </summary> /// <param name="context"></param> public override void onentry(aspectcontext context) { console.write("log onentry:"); if (context != null && context.args != null) console.writeline("{0}({1})", context.name, string.join(",", context.args)); } #endregion #region 调用结束 /// <summary> /// /// </summary> /// <param name="context"></param> public override void onexit(aspectcontext context) { console.writeline("log onexit: " + context.name + (context.result != null ? " result: " + context.result.tostring() : "") + "\r\n"); } #endregion }
上一篇: 不想狗子乱跑把他栓桌子上
下一篇: C++中函数参数的扩展