转自:https://blog.csdn.net/educast/article/details/6565447#
动态代理的原理
原理其实很简单,就是在运行时生成新的对象,姑且叫做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;
- /// <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>");
- }
- }
- 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();
- }
- 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.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();
- }
- }
- 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
执行完毕