动态代理的原理
原理其实很简单,就是在运行时生成新的对象,姑且叫做T,并使T继承自需要代理的原对象,调用过程实际是调用了新的对象T.
通过对T中方法或属性等,添加些自定义的操作,从而实现对原对象访问的封装.
动态代理实现(利用castle)
castle的动态代理需要下面几步
简单拦截器实现代码: 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; /// <summary> /// 拦截器示例 /// </summary> 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 + "<br>"); } }
示例中使用的接口 : 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; /// <summary> ///IPerson 的摘要说明 /// </summary> public interface IPerson { /// <summary> /// 姓名 /// </summary> string Name { get; } /// <summary> /// 地址 /// </summary> string Address { get; } /// <summary> /// 正在做什么 /// </summary> /// <returns></returns> 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; /// <summary> ///Person 的摘要说明 /// </summary> 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<IPerson>(new Person(), Interceptor); //执行方法看效果 p.Doing(); } }
执行的效果就是在页面上输出4句话,如下
开始进入拦截器
开始执行 Doing
执行结果 我正在写blog
执行完毕
动态代理的应用
这个我就不罗唆说了,随便搜一下,大把的,只说一句.
主要用于和业务无关几乎每个方法都要用到的操作,如权限验证,日志记录,自动事务控制....反正很多了.