.net 自定义AOP,透明代理与真实代理

Posted 听哥哥的话

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.net 自定义AOP,透明代理与真实代理相关的知识,希望对你有一定的参考价值。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting;
using NewAop;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Services;

namespace NewAop
{  /// <summary>
   /// IAopOperator AOP操作符接口,包括前处理和后处理 
   /// </summary>
    public interface IAopOperator
    {
        void PreProcess(IMessage requestMsg);
        void PostProcess(IMessage requestMsg, IMessage Respond);
    }
    /// <summary>
    /// MethodAopSwitcherAttribute 用于决定一个被AopProxyAttribute修饰的class的某个特定方法是否启用截获 。
    /// 创建原因:绝大多数时候我们只希望对某个类的一部分Method而不是所有Method使用截获。
    /// 使用方法:如果一个方法没有使用MethodAopSwitcherAttribute特性或使用MethodAopSwitcherAttribute(false)修饰,
    ///       都不会对其进行截获。只对使用了MethodAopSwitcherAttribute(true)启用截获。 
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
    public class MethodAopSwitcherAttribute : Attribute
    {
        private int useAspect = 0; //记录类型
        private string userlog = "";    //记录详细信息
        public MethodAopSwitcherAttribute(int useAop, string log)
        {
            this.useAspect = useAop;
            this.userlog = log;
        }

        public int UseAspect
        {
            get
            {
                return this.useAspect;
            }
        }
        public string Userlog
        {
            get
            {
                return this.userlog;
            }
        }
    }
    /// <summary>
    /// IAopProxyFactory 用于创建特定的Aop代理的实例,IAopProxyFactory的作用是使AopProxyAttribute独立于具体的AOP代理类。
    /// </summary>
    public interface IAopProxyFactory
    {
        AopProxyBase CreateAopProxyInstance(MarshalByRefObject obj, Type type);
    }
    /// <summary>
    /// AopProxyBase 抽象类 所有自定义AOP代理类都从此类派生,覆写IAopOperator接口,实现具体的前/后处理 。 
    /// </summary>
    public abstract class AopProxyBase : RealProxy, IAopOperator
    {
        public readonly MarshalByRefObject target; //默认透明代理 

        #region IAopOperator 成员(两个方法 一个在执行之前调用,另一个在执行之后调用,具体实现代码写在AopControlProxy类中)
        public abstract void PreProcess(IMessage requestMsg);  //方法执行的预处理逻辑
        public abstract void PostProcess(IMessage requestMsg, IMessage Respond);  //方法执行结束的处理逻辑
        #endregion

        public AopProxyBase(MarshalByRefObject obj, Type type)
            : base(type)
        {
            this.target = obj;
        }

        #region Invoke 重写基方法
        public abstract override IMessage Invoke(IMessage msg);

        #endregion
    }
    /// <summary>
    /// AopProxyAttribute
    /// AOP代理特性,如果一个类想实现具体的AOP,只要实现AopProxyBase和IAopProxyFactory,然后加上该特性即可。 
    /// </summary>

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class AopProxyAttribute : ProxyAttribute
    {
        private IAopProxyFactory proxyFactory = null;

        public AopProxyAttribute(Type factoryType)
        {
            this.proxyFactory = (IAopProxyFactory)Activator.CreateInstance(factoryType);
        }

        #region 创建实例
        /// <summary>
        /// 获得目标对象的自定义透明代理
        /// </summary>
        public override MarshalByRefObject CreateInstance(Type serverType)//serverType是被AopProxyAttribute修饰的类
        {
            //未初始化的实例的默认透明代理
            MarshalByRefObject target = base.CreateInstance(serverType); //得到位初始化的实例(ctor未执行)
            object[] args = { target, serverType };
            //AopProxyBase rp = (AopProxyBase)Activator.CreateInstance(this.realProxyType ,args) ; //Activator.CreateInstance在调用ctor时通过了代理,所以此处将会失败

            //得到自定义的真实代理
            AopProxyBase rp = this.proxyFactory.CreateAopProxyInstance(target, serverType);//new AopControlProxy(target ,serverType) ;
            return (MarshalByRefObject)rp.GetTransparentProxy();
        }
        #endregion
    }
    public class AopControlProxyFactory : IAopProxyFactory
    {
        #region IAopProxyFactory 成员
        public AopProxyBase CreateAopProxyInstance(MarshalByRefObject obj, Type type)
        {
            return new AopControlProxy(obj, type);
        }
        #endregion
    }
    public class AopControlProxy : AopProxyBase
    {
        public AopControlProxy(MarshalByRefObject obj, Type type)
            : base(obj, type)   //指定调用基类中的构造函数
        {
        }

        public override void PreProcess(IMessage requestMsg)
        {

            Console.WriteLine("目标方法运行开始之前");
            return;
        }

        public override void PostProcess(IMessage requestMsg, IMessage Respond)
        {
            Console.WriteLine("目标方法运行结束之后");
        }
        public override IMessage Invoke(IMessage msg)
        {
            int useAspect = 0;
            string uselog = "";
            IMethodCallMessage call = (IMethodCallMessage)msg;

            //查询目标方法是否使用了启用AOP的MethodAopSwitcherAttribute
            foreach (Attribute attr in call.MethodBase.GetCustomAttributes(false))
            {
                MethodAopSwitcherAttribute mehodAopAttr = attr as MethodAopSwitcherAttribute;
                if (mehodAopAttr != null)
                {
                    useAspect = mehodAopAttr.UseAspect;
                    uselog = mehodAopAttr.Userlog;

                }


                if (useAspect == 2)
                {
                    IMethodCallMessage callMsg = msg as IMethodCallMessage;
                    this.PostProcess(msg, callMsg);   //执行方法之前的操作
                }
                if (useAspect == 1)
                {
                    this.PreProcess(msg);   //执行方法之前的操作
                }
            }
            //如果触发的是构造函数,此时target的构建还未开始
            IConstructionCallMessage ctor = call as IConstructionCallMessage;
            if (ctor != null)
            {
                //获取最底层的默认真实代理
                RealProxy default_proxy = RemotingServices.GetRealProxy(this.target);

                default_proxy.InitializeServerObject(ctor);
                MarshalByRefObject tp = (MarshalByRefObject)this.GetTransparentProxy(); //自定义的透明代理 this

                return EnterpriseServicesHelper.CreateConstructionReturnMessage(ctor, tp);
            }



            #region 调用目标方法代码
            IMethodMessage result_msg;
            result_msg = RemotingServices.ExecuteMessage(this.target, call);
            //IMethodReturnMessage result_msg = RemotingServices.ExecuteMessage(this.target, call); 
            #endregion
            if (useAspect == 1)
            {
                this.PostProcess(msg, result_msg);      //执行方法结束后的操作
            }
            return result_msg;


        }
    }
    //如果在类上添加该代码 会导致没有添加属性的代码也会被带入Invoke中
    //导致其他方法执行IMethodCallMessage callMsg = msg as IMethodCallMessage;  return new ReturnMessage(callMsg.InArgs, null, 0, null, callMsg);
    //最终导致其他方法的代码无法运行
    [AopProxy(typeof(AopControlProxyFactory))] //将自己委托给AOP代理AopControlProxy,(最好不要添加该代码)
    public class Exameplec : ContextBoundObject//放到特定的上下文中,该上下文外部才会得到该对象的透明代理
    {
        private string name;
        public Exameplec(string a)
        {
            this.name = a;
        }
        [MethodAopSwitcher(1, "参数1")]
        //[MethodAopSwitcher(2, "参数2")]
        public void say_hello()
        {
            Console.WriteLine("say hello");
        }
        public void sayByeBye()
        {
            Console.WriteLine("say good bye");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //try
            //{
            Exameplec epc = new Exameplec("添加代理的方法");
            epc.say_hello();
            Console.WriteLine("");
            Console.WriteLine("--------------------------这是分隔符--------------------------------");


            Exameplec epcs = new Exameplec("未添加代理的方法");
            epcs.sayByeBye();
            Console.WriteLine("--------------------------这是分隔符--------------------------------");

            //}
            //catch
            //{
            //    Console.WriteLine("报错了");
            //}
            Console.ReadLine();
        }
    }
}

 

以上是关于.net 自定义AOP,透明代理与真实代理的主要内容,如果未能解决你的问题,请参考以下文章

再话AOP,从简化缓存操作说起

AOP和动态代理-自定义注解切入使用-01

AOP和动态代理-自定义注解切入使用-01

AOP和动态代理-自定义注解切入使用-01

代理模式

03-spring框架—— AOP 面向切面编程