动态代理的原理
原理其实很简单,就是在运行时生成新的对象,姑且叫做T,并使T继承自需要代理的原对象,调用过程实际是调用了新的对象T.
通过对T中方法或属性等,添加些自定义的操作,从而实现对原对象访问的封装.
动态代理实现(利用castle)
castle的动态代理需要下面几步
- 自定义一个拦截器,必须实现 IInterceptor 接口
- 使用 ProxyGenerator 对象创建代理对象,对象中包含很多方法
- 对原对象的所有操作,都使用代理对象代替
- 在拦截器的方法中,加入自定义的操作,比如 记录参数调用日志,异常记录等.
简单拦截器实现代码: SampleInterceptor.cs
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using Castle.Core.Interceptor; using System.Reflection; ////// 拦截器示例 /// public class SampleInterceptor : IInterceptor { public SampleInterceptor() { // //TODO: 在此处添加构造函数逻辑 // } public void Intercept(IInvocation invocation) { output("开始进入拦截器"); MethodInfo concreteMethod = invocation.GetConcreteMethod(); if (!invocation.MethodInvocationTarget.IsAbstract) { output("开始执行 " + concreteMethod.Name); //执行原对象中的方法 invocation.Proceed(); output("执行结果 " + invocation.ReturnValue); } output("执行完毕"); } private void output(string Message) { HttpContext.Current.Response.Write(Message + "
"); } }
示例中使用的接口 : IPerson.cs
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; //////IPerson 的摘要说明 /// public interface IPerson { ////// 姓名 /// string Name { get; } ////// 地址 /// string Address { get; } ////// 正在做什么 /// ///string Doing(); }
对接口的实现:Person.cs
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; //////Person 的摘要说明 /// public class Person : IPerson { public Person() { // //TODO: 在此处添加构造函数逻辑 // } #region IPerson 成员 public string Name { get { return "我是花生米"; } } public string Address { get { return "我住在 http://pignut-wang.iteye.com/ "; } } public string Doing() { return "我正在写blog"; } #endregion }
所有要使用到的对象都准备好了,下面就是调用的代码
using System; using System.Configuration; using System.Data; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using Castle.DynamicProxy; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //创建拦截器对象 SampleInterceptor Interceptor = new SampleInterceptor(); //给person类生成代理 ProxyGenerator Generator = new ProxyGenerator(); IPerson p = Generator.CreateInterfaceProxyWithTarget(new Person(), Interceptor); //执行方法看效果 p.Doing(); } }
执行的效果就是在页面上输出4句话,如下
开始进入拦截器
开始执行 Doing
执行结果 我正在写blog
执行完毕
动态代理的应用
这个我就不罗唆说了,随便搜一下,大把的,只说一句.
主要用于和业务无关几乎每个方法都要用到的操作,如权限验证,日志记录,自动事务控制....反正很多了.