• .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;
    using System.ServiceModel;
    using System.Runtime.Serialization;
    
    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,Inherited =true)]
        public class MethodAopSwitcherAttribute : Attribute
        {
            private int useAspect = 0; //记录类型
            private string userlog = "";    //记录详细信息
            public MethodAopSwitcherAttribute(int useAop=0, 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(true))
                {
                    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);   //执行方法之前的操作
                    }
                }
    
                #region 如果触发的是构造函数,此时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);
                }
                #endregion
    
                #region 调用目标方法代码
                IMethodMessage result_msg;
                result_msg = RemotingServices.ExecuteMessage(this.target, call);
                #endregion
    
                //执行方法结束后的操作
                this.PostProcess(msg, result_msg);
                return result_msg;
    
    
            }
        }
    
        
    
        public interface IExameplec
        {
           
            void say_hello();
    
            void sayByeBye();
    
    
        }
        public class ExameplecProxy : IExameplec
        {
            public IExameplec exp { get; set; }
            public ExameplecProxy(string a)
            {
                exp = new Exameplec(a);
            }
    
            public void say_hello()
            {
                var t = Convert.ChangeType(exp, exp.GetType());
                (t as dynamic).say_hello();
                //((Exameplec)exp).say_hello();
            }
            public void sayByeBye()
            {
                exp.sayByeBye();
            }
        }
        //如果在类上添加该代码 会导致没有添加属性的代码也会被带入Invoke中
        //导致其他方法执行IMethodCallMessage callMsg = msg as IMethodCallMessage;  return new ReturnMessage(callMsg.InArgs, null, 0, null, callMsg);
        //最终导致其他方法的代码无法运行
        [AopProxyAttribute(typeof(AopControlProxyFactory))] //将自己委托给AOP代理AopControlProxy,(最好不要添加该代码)
        public partial class Exameplec : ContextBoundObject, IExameplec// //放到特定的上下文中,该上下文外部才会得到该对象的透明代理
        {
            
            private string name;
            public Exameplec()
            {
               
            }
    
            public Exameplec(string a)
            {
                var t = this.GetType().GetMethod("say_hello").GetCustomAttributes(true)[0] as MethodAopSwitcherAttribute;
                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)
            {
    
                ExameplecProxy epc = new ExameplecProxy("添加代理的方法");
                epc.say_hello();
                Console.WriteLine("");
                Console.WriteLine("--------------------------这是分隔符--------------------------------");
    
                
    
                //Exameplec epcs = new Exameplec("未添加代理的方法");
                //epcs.sayByeBye();
                //Console.WriteLine("--------------------------这是分隔符--------------------------------");
    
                //Console.ReadLine();
            }
        }
    }
  • 相关阅读:
    Android -- BroadCastReceiver的简单使用
    iOS-UITextField 全面解析
    iOS判断对象相等 重写isEqual、isEqualToClass、hash
    iOS开发 之 不要告诉我你真的懂isEqual与hash!
    浅谈 Objective-C 下对象的初始化
    iOS学习之Object-C语言继承和初始化方法
    Objective-c 中如何重写父类的初始化方法
    OC学习篇之---类的初始化方法和点语法的使用
    iOS7实现带文本输入框的UIAlertView及获取TextField文本内容
    UIALertView的基本用法与UIAlertViewDelegate对对话框的事件处理方法
  • 原文地址:https://www.cnblogs.com/kexb/p/5839149.html
Copyright © 2020-2023  润新知