C#簡單實現Aop實體屬性攔截
阿新 • • 發佈:2020-10-26
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 {View Codepublic 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 + ">>"; } } }View Code
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; } } }View Code
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