zoukankan      html  css  js  c++  java
  • 利用Attribute实现Aop

    Aop“面向切面编程”,与OOP“面向对象编程”一样是一种编程思路。个人理解:在不改变原有逻辑的基础上,注入其他行为。

    基础代码(仿MVC拦截器实现)

    namespace HGL.Toolkit.Aop
    {
        [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
        public sealed class AopAttribute : ContextAttribute, IContributeObjectSink
        {
            public AopAttribute() : base("Aop") { }
    
            //实现IContributeObjectSink接口当中的消息接收器接口
            public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink next)
            {
                return new AopProxy(next);
            }
        }
    
        [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
        public class AopMethodAttribute : Attribute
        {
            /// <summary>
            /// 方法执行之前,执行代码
            /// </summary>
            public virtual bool OnMethodExecuting(System.Web.HttpContext context)
            {
                return true;
            }
    
            /// <summary>
            /// 方法执行之后,执行代码
            /// </summary>
            public virtual bool OnMethodExecuted(System.Web.HttpContext context)
            {
                return true;
            }
        }
    }
    
    namespace HGL.Toolkit.Aop
    {
        public sealed class AopProxy : IMessageSink
        {
            //下一个接收器
            private IMessageSink nextSink;
    
            public IMessageSink NextSink
            {
                get { return nextSink; }
            }
    
            public AopProxy(IMessageSink nextSink)
            {
                this.nextSink = nextSink;
            }
    
            //同步处理方法
            public IMessage SyncProcessMessage(IMessage msg)
            {
                IMessage retMsg = null;
    
                //方法调用消息接口
                IMethodCallMessage call = msg as IMethodCallMessage;
    
                var attributes = Attribute.GetCustomAttributes(call.MethodBase, typeof(AopMethodAttribute));
    
                //如果被调用的方法没打AopMethodAttribute标签
                if (call == null || attributes.Count() == 0)
                {
                    retMsg = nextSink.SyncProcessMessage(msg);
                }
                //如果打了AopMethodAttribute标签
                else
                {
                    foreach (var attribute in attributes)
                    {
                        var obj = attribute.GetType();
    
                        var executing = obj.GetMethod("OnMethodExecuting");
                        if (executing != null)
                        {
                            var context=System.Web.HttpContext.Current;
                            executing.Invoke(attribute, new object[] { context });
                        }
                    }
    
                    retMsg = nextSink.SyncProcessMessage(msg);
    
                    foreach (var attribute in attributes)
                    {
                        var obj = attribute.GetType();
    
                        var executed = obj.GetMethod("OnMethodExecuted");
                        if (executed != null)
                        {
                            var context = System.Web.HttpContext.Current;
                            executed.Invoke(attribute, new object[] { context });
                        }
                    }
                }
    
                return retMsg;
            }
    
            //异步处理方法(不需要)
            public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
            {
                return null;
            }
        }
    }
    

     使用注意:

    1.使用到Aop的类必须继承ContextBoundObject
    2.使用到Aop的方法存在的类必须添加[Aop]特性
    3.哪个方法需要实现Aop,就给那个方法添加[AopMethod]特性
    
    AopMethod未实现任何业务逻辑,使用者需要重写该attribute
    
    /// <summary>
    /// 方法执行之前,执行代码
    /// </summary>
    public virtual bool OnMethodExecuting()
    {
        return true;
    }
    
    /// <summary>
    /// 方法执行之后,执行代码
    /// </summary>
    public virtual bool OnMethodExecuted()
    {
        return true;
    }
    

     待续......(将执行前和执行后的方法使用代理委托机制,实现二次开发)

  • 相关阅读:
    MVC 后台DataTable 前台遍历
    oracle 创建表空间详细介绍
    C# Chart 折线图 多条数据展示
    ASP.NET Request.QueryString 出现乱码问题
    生成XML文件
    什么是Intent(意图)
    HTTP错误405-Method Not Allowed
    通过剪切板传递数据—— 传递一个对象
    Linux下crontab命令的用法
    Redis使用介绍
  • 原文地址:https://www.cnblogs.com/xishuqingchun/p/4135329.html
Copyright © 2011-2022 走看看