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;
        }
    }
}
View Code

 

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

  

posted @ 2020-10-26 09:50  白色風車  阅读(596)  评论(0编辑  收藏  举报