利用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; }
待续......(将执行前和执行后的方法使用代理委托机制,实现二次开发)