zoukankan      html  css  js  c++  java
  • .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();
            }
        }
    }
  • 相关阅读:
    面向对象的继承关系体现在数据结构上时,如何表示
    codeforces 584C Marina and Vasya
    codeforces 602A Two Bases
    LA 4329 PingPong
    codeforces 584B Kolya and Tanya
    codeforces 584A Olesya and Rodion
    codeforces 583B Robot's Task
    codeforces 583A Asphalting Roads
    codeforces 581C Developing Skills
    codeforces 581A Vasya the Hipster
  • 原文地址:https://www.cnblogs.com/kexb/p/5839149.html
Copyright © 2011-2022 走看看