欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# 使用Emit实现动态AOP框架 (二)

程序员文章站 2022-04-09 09:28:31
实现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
    }