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;
    }
    

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

  • 相关阅读:
    unicode字符集
    534,rgba()和opacity的透明效果有什么不同?
    1004,js中的fliter
    1003,js array map()方法
    JavaScript 数据类型和数据结构
    JavaScript实现浮点数运算问题
    Chrome浏览器不能正确加载更新后JavaScript和Css文件原因及解决方法
    MySQL安装版与压缩版安装方法
    VUE列表渲染 FOR-IN和FOR-OF的区别
    for、for-in、for-of、forEach的区别
  • 原文地址:https://www.cnblogs.com/xishuqingchun/p/4135329.html
Copyright © 2011-2022 走看看