• 利用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;
    }
    

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

  • 相关阅读:
    Configure文件学习
    实用文章:常用开源协议详细解析
    openwrt的sysupgrade和factory固件的区别
    Linux块设备和字符设备
    eclipse代码补全按键修改成Tab
    Hadoop环境搭载
    比特币中难度调整
    共识机制
    比特币交易本质--UTXO(Unspent Transaction Output)
    多重签名
  • 原文地址:https://www.cnblogs.com/xishuqingchun/p/4135329.html
Copyright © 2020-2023  润新知