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

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

  • 相关阅读:
    What is PE ?
    指针和引用(int*、int&、int*&、int&*、int**)
    诺顿12 免许可 英文版 Symantec Endpoint Protection 12.1.671.4971 下载
    RadControls for ASP.NET AJAX Q2 2011 最新版下载+源码下载
    请大家给小弟 改个SQL的错 谢谢啦!!
    [置顶]DAEMON Tools Pro Advanced 4.41.0314.0232 破解版
    Setting Environment Variable PATH on Ubuntu
    小弟的程序有点问题 请高手帮忙改一下
    Session 有没有必要使用它
    ASP.NET 2.0加密Web.config 配置文件
  • 原文地址:https://www.cnblogs.com/xishuqingchun/p/4135329.html
Copyright © 2020-2023  润新知