相比之前一篇remoting实现的AOP,这次用RealProxy和ProxyAttribute实现的简单许多。
代码如下:
首先是透明代理,该类在运行时会自动根据类的特性去代理其被代理对象
using System; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Proxies; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting; using System.Runtime.Remoting.Services; using System.Collections.Generic; namespace AOPProxy.AOP { public class AOPProxyBase : RealProxy { private Dictionary<string, MarshalByRefObject> _targetDict = null; private Dictionary<string, IAOPInterceptAchieveBase> _aopAchieveDict = new Dictionary<string, IAOPInterceptAchieveBase>(); private static Dictionary<string, AOPProxyBase> _aopProxy = new Dictionary<string, AOPProxyBase>(); private AOPProxyBase(Type type, Dictionary<string, MarshalByRefObject> targetDict, Dictionary<string, IAOPInterceptAchieveBase> aopAchieveDict) : base(type) { this._targetDict = targetDict; this._aopAchieveDict = aopAchieveDict; } public static AOPProxyBase GetBaseProxyInstance(Type type, Dictionary<string, MarshalByRefObject> targetDict, Dictionary<string, IAOPInterceptAchieveBase> aopAchieveDict) { string typeName = type.FullName; if (_aopProxy.ContainsKey(typeName)==false) { _aopProxy.Add(typeName, new AOPProxyBase(type, targetDict, aopAchieveDict)); } return _aopProxy[typeName]; } //对应添加了AOPProxy特性的类,系统会自动调用该方法 public override IMessage Invoke(IMessage msg) { string targetTypeName = Convert.ToString(msg.Properties["__TypeName"]).Split(',')[0]; IMethodReturnMessage result = null; bool isAOP = false;//是否需要AOP拦截 //构造函数,只有ContextBoundObject(Inherit from MarshalByRefObject)对象才能截获构造函数 if (msg is IConstructionCallMessage) { IConstructionCallMessage cusMethod = msg as IConstructionCallMessage; RealProxy defaultProxy = RemotingServices.GetRealProxy(_targetDict[targetTypeName]); //如果不做下面这一步,_targetDict[targetTypeName]还是一个没有直正实例化被代理对象的透明代理, //这样的话,会导致没有直正构建对象。 defaultProxy.InitializeServerObject(cusMethod); //本类是一个RealProxy,它可通过GetTransparentProxy函数得到透明代理 result = EnterpriseServicesHelper.CreateConstructionReturnMessage(cusMethod, (MarshalByRefObject)GetTransparentProxy()); } else if (msg is IMethodCallMessage) { IMethodCallMessage method = (IMethodCallMessage)msg; AOPMethodBaseAttribute aopMethod = null; //查询目标方法是否使用了启用AOP的AOPMethodAttribute foreach (Attribute attr in method.MethodBase.GetCustomAttributes(false)) { if (attr is AOPMethodBaseAttribute) { aopMethod = attr as AOPMethodBaseAttribute; isAOP = true; break; } } if (isAOP)//需要AOP拦截 { if (aopMethod.AopLocation == AOPLocation.Before) { bool check = _aopAchieveDict[aopMethod.NameSpaceClass].BeforeAchieve(method); if (check) { result = RemotingServices.ExecuteMessage(_targetDict[targetTypeName], method); } } else if(aopMethod.AopLocation == AOPLocation.After) { result = RemotingServices.ExecuteMessage(_targetDict[targetTypeName], method); _aopAchieveDict[aopMethod.NameSpaceClass].AfterAchieve(result); } else { bool check = _aopAchieveDict[aopMethod.NameSpaceClass].BeforeAchieve(method); if (check) { result = RemotingServices.ExecuteMessage(_targetDict[targetTypeName], method); _aopAchieveDict[aopMethod.NameSpaceClass].AfterAchieve(result); } } } else//不需要AOP拦截,直接执行目标方法 { result = RemotingServices.ExecuteMessage(_targetDict[targetTypeName], method); } } return result; } } }
using System; using System.Runtime.Remoting.Proxies; using System.Collections.Generic; namespace AOPProxy.AOP { [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class AOPProxyBaseAttribute : ProxyAttribute { private static Dictionary<string, IAOPInterceptAchieveBase> _aopAchieveDict = new Dictionary<string, IAOPInterceptAchieveBase>(); private static Dictionary<string, MarshalByRefObject> _targetDict = new Dictionary<string, MarshalByRefObject>(); public AOPProxyBaseAttribute(Type type) { try { object obj = Activator.CreateInstance(type); if (obj is IAOPInterceptAchieveBase) { if(_aopAchieveDict.ContainsKey(((IAOPInterceptAchieveBase)obj).GetType().FullName)==false) _aopAchieveDict.Add(((IAOPInterceptAchieveBase)obj).GetType().FullName, (IAOPInterceptAchieveBase)obj); } else { throw new ArgumentException("特性的参数必须是实现IAOPInterceptAchieve接口的对象"); } } catch (MissingMemberException e) { throw new MissingMemberException("实现IAOPInterceptAchieve接口的自定义代理类必须定义无参的构造函数",e); } } //覆写CreateInstance函数,返回我们自建的代理 //该方法会在需要被代理的类在实例化时被创建 public override MarshalByRefObject CreateInstance(Type serverType)//serverType是被AOPAttribute修饰的类 { //未初始化的实例的默认透明代理 MarshalByRefObject target = base.CreateInstance(serverType); //得到未初始化的实例 if (_targetDict.ContainsKey(serverType.FullName) == false) _targetDict.Add(serverType.FullName, target); //得到自定义的真实代理 AOPProxyBase rp = AOPProxyBase.GetBaseProxyInstance(serverType, _targetDict, _aopAchieveDict);//new AOPProxyBase(serverType, _targetDict, _aopAchieveDict); return (MarshalByRefObject)rp.GetTransparentProxy(); } } }
using System; namespace AOPProxy.AOP { [AttributeUsage(AttributeTargets.Method,AllowMultiple=false)] public class AOPMethodBaseAttribute : Attribute { private AOPLocation _aopLocation; private string _nameSpaceClass; public string NameSpaceClass { get { return _nameSpaceClass; } set { _nameSpaceClass = value; } } public AOPLocation AopLocation { get { return _aopLocation; } set { _aopLocation = value; } } public AOPMethodBaseAttribute(AOPLocation loc,string ncl) { this._aopLocation = loc; this._nameSpaceClass = ncl; } } public enum AOPLocation { Before, After, All } }
using System.Runtime.Remoting.Messaging; namespace AOPProxy.AOP { /// <summary> /// 被拦截方法的前后的额外处理逻辑接口 /// </summary> public interface IAOPInterceptAchieveBase { bool BeforeAchieve(IMethodCallMessage callMsg); bool AfterAchieve(IMethodReturnMessage returnMsg); } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using AOPProxy.AOP; namespace AOPProxy { class Program { static void Main(string[] args) { Test1Instance t1 = new Test1Instance(); t1.Rxb1Method(); Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); Test2Instance t = new Test2Instance(); t.Rxb2Method(); t.Test2Method("我是目标方法的参数"); Console.ReadLine(); } } [AOPProxyBaseAttribute(typeof(AOPDataProxy))] [AOPProxyBaseAttribute(typeof(AOPLogProxy))] public class Test2Instance : TestBase { [AOPMethodBaseAttribute(AOPLocation.All, "AOPProxy.AOPDataProxy")] public string Test2Method(string s) { Console.WriteLine("TestMethod2-Action…要被拦截的方法…"); return "rxb"; } [AOPMethodBaseAttribute(AOPLocation.All, "AOPProxy.AOPLogProxy")] public void Rxb2Method() { Console.WriteLine("RxbMethod2-Action…要被拦截的方法…"); } } [AOPProxyBaseAttribute(typeof(AOPLogProxy))] public class Test1Instance : TestBase { public string Test1Method(string s) { Console.WriteLine("TestMethod1-Action…要被拦截的方法…"); return "rxb"; } [AOPMethodBaseAttribute(AOPLocation.Before, "AOPProxy.AOPLogProxy")] public void Rxb1Method() { Console.WriteLine("RxbMethod1-Action…要被拦截的方法…"); } } public class TestBase : ContextBoundObject{} }