首页 > 代码库 > 利用Attribute实现Aop

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

 

利用Attribute实现Aop