.net Aop 实现原理
本文实现所有继承BaseModel的类都通过代理拦截
using System; using System.Reflection; using System.Collections.Generic; using System.Runtime.Remoting.Proxies; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Activation; namespace Soffice.DevelopFramework.Common.DataAccess { [AopAttribute] public class BaseModel : ContextBoundObject { private Dictionary<string, object> Fields = new Dictionary<string, object>(); public void AddField(string fieldName, object value) { Fields.Add(fieldName, value); } public Dictionary<string, object> GetFields() { return Fields; } } class AopAttribute : ProxyAttribute { public override MarshalByRefObject CreateInstance(Type serverType) { AopProxy realProxy = new AopProxy(serverType); return realProxy.GetTransparentProxy() as MarshalByRefObject; } } class AopProxy : RealProxy { MethodInfo method = null; public AopProxy(Type serverType) : base(serverType) { method = serverType.GetMethod("AddField"); } public override IMessage Invoke(IMessage msg) { //消息拦截之后,就会执行这里的方法。 if (msg is IConstructionCallMessage) // 如果是构造函数,按原来的方式返回即可。 { IConstructionCallMessage constructCallMsg = msg as IConstructionCallMessage; IConstructionReturnMessage constructionReturnMessage = this.InitializeServerObject((IConstructionCallMessage)msg); RealProxy.SetStubData(this, constructionReturnMessage.ReturnValue); return constructionReturnMessage; } else if (msg is IMethodCallMessage) //如果是方法调用(属性也是方法调用的一种) { IMethodCallMessage callMsg = msg as IMethodCallMessage; object[] args = callMsg.Args; IMessage message; try { if (callMsg.MethodName.StartsWith("set_") && args.Length == 1) { //这里检测到是set方法,然后应怎么调用对象的其它方法呢? method.Invoke(GetUnwrappedServer(), new object[] { callMsg.MethodName.Substring(4), args[0] });//对属性进行调用 } object o = callMsg.MethodBase.Invoke(GetUnwrappedServer(), args); message = new ReturnMessage(o, args, args.Length, callMsg.LogicalCallContext, callMsg); } catch (Exception e) { message = new ReturnMessage(e, callMsg); } return message; } return msg; } } }