[置顶] Castle 系列: Castle DynamicProxy动态生成透明代理类型

Castle DynamicProxy动态生成透明代理类型,实体不需要继承MarshalByRef、ContextBoundObject便可以实现代理类
基于透明代理的功能,可以实现对方法调用的拦截处理,例如NHibernate用它实现延迟加载
DP的使用非常简单,内部没有使用反射,而是采用Emit、委托等方式生成代理类型,调用真实类的方法,性能方面也没有太多损失

基本示例

引用的命名空间: 

       using Castle.Core.Interceptor;

      using Castle.DynamicProxy;

被代理的实体类:

      public class SimpleSamepleEntity

     {

         public virtual string Name { get; set; }

         public virtual int Age { get; set; }

          public override string ToString()

        {          

     return string.Format("{{ Name: \"{0}\", Age: {1} }}", this.Name, this.Age);
            }

      }

复制代码定义一个拦截器,调用代理类的方法时使用拦截器进行拦截处理:

    public class CallingLogInterceptor : IInterceptor

       {

            private int _indent = 0;
           private void PreProceed(IInvocation invocation)
         {

              if (this._indent > 0)

                Console.Write(" ".PadRight(this._indent * 4, ' '));

              this._indent++;

             Console.Write("Intercepting: " + invocation.Method.Name + "(");

            if (invocation.Arguments != null && invocation.Arguments.Length > 0)

               for (int i = 0; i < invocation.Arguments.Length; i++)
                   {
                if (i != 0) Console.Write(", ");
                      Console.Write(invocation.Arguments == null
                           ? "null"

                            : invocation.Arguments.GetType() == typeof(string)

                             ? "\"" + invocation.Arguments.ToString() + "\""

                              : invocation.Arguments.ToString());
                 }

              Console.WriteLine(")");

           }

           private void PostProceed(IInvocation invocation)

           {

             this._indent--;

         }

            public void Intercept(IInvocation invocation)
           {

             this.PreProceed(invocation);

           invocation.Proceed();

               this.PostProceed(invocation);

         }

        }

复制代码 测试代码:

       ProxyGenerator generator = new ProxyGenerator();

        CallingLogInterceptor interceptor = new CallingLogInterceptor();

      SimpleSamepleEntity entity = generator.CreateClassProxy<SimpleSamepleEntity>(interceptor);

        entity.Name = "Richie";
      entity.Age = 50;
       Console.WriteLine("The entity is: " + entity);
       Console.WriteLine("Type of the entity: " + entity.GetType().FullName);
     Console.ReadKey();

复制代码运行结果:
 
[置顶] Castle 系列: Castle DynamicProxy动态生成透明代理类型_第1张图片
dynamic-proxy-sample-1.JPG(19.01 K)
3/22/2010 12:06:06 AM


上面示例使用CreateClassProxy方法创建了一个代理对象entity,从图中输出的entity类型可以看到他的类型为 Castle.Proxies.SimpleSampleEntity
当调用代理对象的任何方法时,将使用CallingLogInterceptor这个拦截器进行处理,在CallingLogInterceptor中输出了调用日志信息
在拦截器的 接口方法Intercept中,可以修改入参,决定是否调用真实方法,修改返回结果等
可以拦截的方法:
1. 对于Class Proxy类型的代理,因为DP使用继承和override虚方法的方式实现代理,所以被拦截的方法必须为virtual类型,非virtual类型的方法无法拦截
2. 实体继承自Object、MarshalByRefObject等对象的方法,如果在实体类中没有override将无法拦截
DP会将动态创建的代理类型 缓存起来

你可能感兴趣的:(String,object,Interceptor,null,Class,generator)