3、编写增加日志和性能检测功能的代理类
增加记录日志的功能,即功能要求将对每个方法的调用和处理结果输出到Console;增加性能监测。
有两种实现方式 ,注释了其中的一种
| using System; namespace Proxy { // /// <summary> // /// CalProxy 的摘要说明。 // /// </summary> // public class CalProxy:ICalculator // { // private Calculator _Calculator; // public CalProxy() // { // this._Calculator=new Calculator(); // } // private DateTime TimeBegin = System.DateTime.Now; // private void PreDoSomething(int x, int y) // { // TimeBegin = System.DateTime.Now; // Console.Write("Number({0},{1})\n", x, y); // } // //实现add // public virtual int Add(int x, int y) // { // this.PreDoSomething(x,y); // int result = this._Calculator.Add(x,y); // this.PostDoSomething(result); // return result; // } // //实现sub // public virtual int Subtract(int x, int y) // { // this.PreDoSomething(x,y); // int result = this._Calculator.Subtract(x,y); // this.PostDoSomething(result); // return result; // } // private void PostDoSomething(int result) // { // TimeSpan TimeInter =System.DateTime.Now-TimeBegin; // Console.Write(" 运行时间[{0}]\n ", TimeInter); // Console.WriteLine(" 运行结果= {0}\n", result); // } // } /// <summary> /// CalProxy 的摘要说明。 /// </summary> public class CalProxy:Calculator { public CalProxy() {} private DateTime TimeBegin = System.DateTime.Now; private void PreDoSomething(int x, int y) { TimeBegin = System.DateTime.Now; Console.Write("Number({0},{1})\n", x, y); } //实现add public override int Add(int x, int y) { this.PreDoSomething(x,y); int result = base.Add(x,y); this.PostDoSomething(result); return result; } //实现sub public override int Subtract(int x, int y) { this.PreDoSomething(x,y); int result = base.Subtract(x,y); this.PostDoSomething(result); return result; } private void PostDoSomething(int result) { TimeSpan TimeInter =System.DateTime.Now-TimeBegin; Console.Write(" 运行时间[{0}]\n ", TimeInter); Console.WriteLine(" 运行结果= {0}\n", result); } } } |
4、外界的调用方式
| ICalculator ICal=new Proxy.CalProxy(); ICal.Add(5,3); ICal.Subtract(7,2); |
运行程序的结果:
Number(5,3)
运行时间[00:00:02.0156250]
运行结果= 8
Number(7,2)
运行时间[00:00:03]
运行结果= 5
方案二:通过使用Castle.DynamicProxy,实现Iinterceptor解决
步骤1,2与解决问题
3、实现StandardInterceptor,增加日志和性能监测功能
StandardInterceptor是接口Iinterceptor的一个实现类,我们实现StandardInterceptor
| using System; using System.Collections; using Castle.DynamicProxy; namespace Proxy { /// <summary> /// ProxyInterceptor 拦截器 实现了日志和性能监测 /// </summary> public class ProxyInterceptor:StandardInterceptor { private System.DateTime TimeBegin=System.DateTime.Now; public ProxyInterceptor() {} protected override void PostProceed(IInvocation invocation, ref object returnValue, params object[] arguments) { TimeSpan TimeInter =System.DateTime.Now-TimeBegin; Console.Write(" 运行时间[{0}]\n ", TimeInter); Console.WriteLine(" 运行结果= {0}\n", returnValue); base.PostProceed(invocation, ref returnValue, arguments); } protected override void PreProceed(IInvocation invocation, params object[] args) { Console.Write("Number({0},{1})\n", args[0], args[1]); TimeBegin=System.DateTime.Now; base.PreProceed(invocation, args); } public override object Intercept(IInvocation invocation, params object[] args) { PreProceed(invocation, args); object retValue = invocation.Proceed( args ); PostProceed(invocation, ref retValue, args); return retValue; } } } |
4、使用Castle.DynamicProxy调用
| ProxyGenerator generator = new ProxyGenerator(); object proxy = generator.CreateClassProxy(typeof(Calculator), new ProxyInterceptor()); ICalculator ICalCastle=proxy as ICalculator; ICalCastle.Add(5,3); ICalCastle.Subtract(7,2); |
实现过程:首先通过代码生成完成一个代理类,该代理类继承自要织入的类。然后在代理类中覆盖要拦截的方法,并在覆盖的方法中封装Invocation对象,并传给用户传入的Intercepter对象的Intercept方法。在Intercept方法依次调用Intercepter的PreProcess,通过Invocation传入的Delegate指向的回调函数,Intercepter的PostProcess方法,从而达到拦截的目的。
意义
在aop领域 可以将日志,事务,缓存等附加功能用此实现。
更多内容请看PCdog.com--.NET基础介绍 .NET应用研究 代理服务器技术专题
