C#简单实现Aop实体属性拦截
1
using System; using System.Reflection; using System.Runtime.Remoting; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Proxies; using System.Runtime.Remoting.Services; namespace AopTest.Entity { class AopAttribute : ProxyAttribute { public override MarshalByRefObject CreateInstance(Type serverType) { AopProxy realProxy = new AopProxy(serverType, base.CreateInstance(serverType)); return realProxy.GetTransparentProxy() as MarshalByRefObject; } } class AopProxy : RealProxy { MethodInfo Setmethod; MethodInfo ListenerLog; MarshalByRefObject _target = null; public AopProxy(Type serverType, MarshalByRefObject target) : base(serverType) { _target = target; Setmethod = serverType.GetMethod("Set", BindingFlags.NonPublic | BindingFlags.Instance); ListenerLog = serverType.GetMethod("ListenerLog", BindingFlags.NonPublic | BindingFlags.Instance); } public override IMessage Invoke(IMessage msg) { if (msg != null) { if (msg is IConstructionCallMessage) { IConstructionCallMessage constructCallMsg = msg as IConstructionCallMessage; //IConstructionReturnMessage constructionReturnMessage = this.InitializeServerObject((IConstructionCallMessage)msg); //RealProxy.SetStubData(this, constructionReturnMessage.ReturnValue); //return constructionReturnMessage; RealProxy defaultProxy = RemotingServices.GetRealProxy(_target); //如果不做下面这一步,_target还是一个没有直正实例化被代理对象的透明代理, //这样的话,会导致没有直正构建对象。 defaultProxy.InitializeServerObject(constructCallMsg); //本类是一个RealProxy,它可通过GetTransparentProxy函数得到透明代理 return EnterpriseServicesHelper.CreateConstructionReturnMessage(constructCallMsg, (MarshalByRefObject)GetTransparentProxy()); } else if (msg is IMethodCallMessage) { IMethodCallMessage callMsg = msg as IMethodCallMessage; object[] args = callMsg.Args; //System.Windows.Forms.MessageBox.Show(callMsg.MethodBase.ToString()); IMethodReturnMessage methodReturnMessage; methodReturnMessage = RemotingServices.ExecuteMessage(_target, callMsg); if (callMsg.MethodName.StartsWith("set_") && args.Length == 1) { ListenerLog.Invoke(_target, new object[] { "Set", _target.GetType().Name, callMsg.MethodName.Substring(4), args[0] });//属性进行调用 } else if (callMsg.MethodName.StartsWith("get_") && args.Length == 0) { //object val = callMsg.MethodBase.Invoke(_target, null); ListenerLog.Invoke(_target, new object[] { "Get", _target.GetType().Name, callMsg.MethodName.Substring(4), methodReturnMessage.ReturnValue });//属性进行调用 } else if (callMsg.MethodName.Equals("FieldSetter") && args.Length == 3) { ListenerLog.Invoke(_target, new object[] { callMsg.MethodName, _target.GetType().Name, args[1], args[2] });//字段进行调用 } else if (callMsg.MethodName.Equals("FieldGetter") && args.Length == 3) { callMsg.MethodBase.Invoke(_target, args); ListenerLog.Invoke(_target, new object[] { callMsg.MethodName, _target.GetType().Name, args[1], args[2] });//字段进行调用 } else { ListenerLog.Invoke(_target, new object[] { callMsg.MethodName, _target.GetType().Name, args, methodReturnMessage.ReturnValue });//方法进行调用 } //methodReturnMessage = RemotingServices.ExecuteMessage(_target, callMsg); return methodReturnMessage; //IMessage message = null; //try //{ // MarshalByRefObject obj = GetUnwrappedServer(); // if (callMsg.MethodName.StartsWith("set_") && args.Length == 1) // { // method.Invoke(obj, new object[] { callMsg.MethodName.Substring(4), args[0] });//对属性进行调用 // } // object o = callMsg.MethodBase.Invoke(obj, args); // message = new ReturnMessage(o, args, args.Length, callMsg.LogicalCallContext, callMsg); //} //catch (Exception e) //{ // message = new ReturnMessage(e, callMsg); //} //return message; } } return msg; } } }
Base类
using System; using System.Diagnostics; using System.Reflection; namespace AopTest.Entity { [AopAttribute] public abstract partial class AopBase : ContextBoundObject { protected void Set(object key, object value) { string loc = GetCallingLocation(9); } protected void ListenerLog(string MethodName, string entitytype, object key, object value) { string str = ""; switch (MethodName) { case "Set": str = GetCallingLocation(9) + entitytype + " 设置属性 " + key + " 值为 " + value; break; case "Get": str = GetCallingLocation(9) + entitytype + " 读取属性 " + key + " 值为 " + value; break; case "FieldSetter": str = GetCallingLocation(9) + entitytype + " 设置字段 " + key + " 值为 " + value; break; case "FieldGetter": str = GetCallingLocation(9) + entitytype + " 读取字段 " + key + " 值为 " + value; break; default: string parameter = ""; foreach (object obj in key as object[]) { parameter += obj.ToString() + ","; } parameter = parameter.TrimEnd(','); str = GetCallingLocation(9) + entitytype + "调用方法 " + MethodName + " 参数 " + parameter + " 返回 " + value.ToString(); break; } Logs(str); } private void Logs(string msg) { } private string GetCallingLocation(int index) { StackTrace trace = new StackTrace(); MethodBase methodName = trace.GetFrame(index).GetMethod(); string className = methodName.ReflectedType.Name; return className + ">>" + methodName.Name + ">>"; } } }
Test
namespace AopTest.Entity { class test : AopBase { public int val = 0; public int Aa { get; set; } public string age { get; set; } public int add(int a, int b) { return a + b; } public static int add2(int a, int b) { return a + b; } } }
test tt = new test(); tt.val = 5; int vv = tt.val; tt.age = "dfefe"; string age = tt.age; int bb = tt.add(44, 55);
拦截效果
Form1>>button1_Click>>test 设置字段 val 值为 5 Form1>>button1_Click>>test 读取字段 val 值为 5 Form1>>button1_Click>>test 设置属性 age 值为 dfefe Form1>>button1_Click>>test 读取属性 age 值为 dfefe Form1>>button1_Click>>test调用方法 add 参数 44,55 返回 99