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 Dynamic Proxy - 2.2_24816
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會將動態創建的代理類型緩存起來
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章