.net 自定义AOP,透明代理与真实代理
2016-09-04 13:32
459 查看
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(); } } }
相关文章推荐
- .net 真实代理和透明代理的交互
- .net 真实代理和透明代理的交互
- .net(c#)获取客户端真实IP,非代理
- Courser ORM FOR .NET 0.3版将引入.NET透明代理机制
- .net中利用代理实现AOP
- 不用Unity库,利用.NET动态代理自己实现AOP
- 你永远获得不到我的真实IP 模拟IP 隐藏IP 代理IP 伪装IP 高匿代理 普匿代理 透明代理IP
- .Net 框架实现AOP(动态代理实现AOP,本文为翻译)
- 多层透明代理,取真实IP地址(转)
- 【.NET中AOP的实现方案】静态代理
- 一起谈.NET技术,.NET中通过代理实现面向方面编程(AOP)
- .Net 动态代理,AOP
- 利用.NET Remoting基础架构中的真实代理/透明代理技术实现了不针对具体类型、具体方法的通用方法调用拦截机制
- 透明代理和真实代理的区别
- ######【spring属性注入(Ioc的DI)总结】:注解方式属性注入,属性名任意.=for理解:Aop注入代理对象时,注入被增强类对象时,属性名为proxy(自定义)。
- .NET 自带的动态代理+Expression 实现AOP
- 基于透明代理的内部类访问抽象 [1] 类型与调用的封装
- 在.NET中实现彩色光标,动画光标和自定义光标[引自孟子前辈作品]
- [导入]在.NET中实现彩色光标,动画光标和自定义光标
- Java初学者如何迈出AOP第一步--使用Java 动态代理实现AOP