C#使用KingAOP实现AOP面向切面编程二

本文继续上篇讲述一下比较复杂点的AOP例子,先新建一个控制台项目,然后同样先在Nuget中搜索安装KingAop到项目中

1、项目结构

2 、定义一个登录实体类User和LoggingAspect切面日志类

 public class User
 {
      public int ID { get; set; }
      public string Name { get; set; }
      public string Pwd { get; set; }
      public string State { get; set; }
      public System.DateTime LoginTime { get; set; }
 }
    /// <summary>
    /// 创建一个日志切面处理类
    /// </summary>
    public class LoggingAspect : OnMethodBoundaryAspect
    {
        public override void OnEntry(MethodExecutionArgs args)
        {
            string logData = CreateLogData("entering", args);
            Console.WriteLine(logData);
        }

        public override void OnException(MethodExecutionArgs args)
        {
            string logData = CreateLogData("exception", args);
            Console.WriteLine(logData);
        }

        public override void OnSuccess(MethodExecutionArgs args)
        {
            string logData = CreateLogData("success", args);
            Console.WriteLine(logData);
        }

        public override void OnExit(MethodExecutionArgs args)
        {
            string logData = CreateLogData("exiting", args);
            Console.WriteLine(logData);
        }

        /// <summary>
        /// AOP处理登录日志逻辑,只需在此进行修改即可,无需修改被切面的处理类
        /// </summary>
        /// <param name="methodStage"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        private string CreateLogData(string methodStage, MethodExecutionArgs args)
        {
            var str = new StringBuilder();
            str.AppendLine();
            str.AppendLine(string.Format(methodStage + " {0} ", args.Method));
            foreach (var argument in args.Arguments)
            {
                //下面利用反射机制获取对象名称和对象属性和属性值
                var argType = argument.GetType();

                str.Append(argType.Name + ": ");

                if (argType == typeof(string) || argType.IsPrimitive)
                {
                    str.Append(argument);
                }
                else
                {
                    foreach (var property in argType.GetProperties())
                    {
                        str.AppendFormat("{0} = {1}; ",
                            property.Name, property.GetValue(argument, null));
                    }
                }
            }
            return str.ToString();
        }
    }

3、定义一个登录业务类Login,并且继承IDynamicMetaObjectProvider类

    /// <summary>
    /// 该类需要继承IDynamicMetaObjectProvider,因为KingAOP是基于动态类型进行操作和绑定的,如不继承是不会进入到刷选器中的相应事件里
    /// 登录功能,只需添加一个LoggingAspect即可实现日志功能,达到业务逻辑和通用处理逻辑的分离
    /// </summary>
    public class Login : IDynamicMetaObjectProvider
    {
        //添加处理日志切面
        [LoggingAspect]
        public void LoginValdate(User entity)
        {
            //只需进行业务逻辑处理,无需进行日志处理,日志处理交给切面处理
            if (entity.Name == "jack" && entity.Pwd == "wang")
            {
                entity.State = "Logged";
            }
            else
            {
                entity.State = "Error";
            }
        }

        /// <summary>
        /// 该类必须实现IDynamicMetaObjectProvider的GetMetaObject方法
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public DynamicMetaObject GetMetaObject(Expression parameter)
        {
            return new AspectWeaver(parameter, this);
        }
    }

4、接下来就是测试代码,如下

    class Program
    {
        static void Main(string[] args)
        {         
            //复杂例子
            Login test = new Login();
            dynamic entity = new User { ID = 99, Name = "Jon", Pwd = "wang", State = "", LoginTime = System.DateTime.Now };
            test.LoginValdate(entity);

            Console.Read();
        }
    }

 

posted @ 2018-11-20 17:05  以德为先  阅读(603)  评论(0编辑  收藏  举报