首页 > 代码库 > .net 自定义AOP,透明代理与真实代理
.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,透明代理与真实代理
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。