動態代理DynamicProxy 介紹

來源:互聯網
上載者:User

我們使用動態代理,主要是因為動態代理擁有這樣的能力--使得某個類型A在啟動並執行時候能轉化為一個指定的介面I,即使這個類型A在定義的時候並沒有從這個指定的介面I繼承。這句話是什麼意思了?還是回到當泛型的參數類型是動態... 一文中的那個例子,在例子中,List<>並沒有從ISimpleList繼承,但是從表面看來,在啟動並執行時候,我們通過動態代理可以以ISimpleList介面來“引用”List<>類型的對象。

動態代理是在運行時在記憶體中構建的一種類型,該類型實現了介面I,但是它將所有的方法調用都轉寄給類型A。

注意,上面我使用了“方法”調用的轉寄,由於,事件、屬性都是方法的變體,所以,對介面中定義的所有元素的Call都可以被動態代理轉寄。那麼,介面(I)中的方法與被代理者(Target)的方法如何匹配起來了?通常的方法是,進行“同名”匹配,比如ISimpleList介面的Add方法就自然匹配到List<>的Add方法。對於複雜的需求,可以定義一個方法名映射表來匹配不同名的方法。

由於,動態代理擁有這種為類型(Target)“換臉”的能力,所以,在很多場合可以使用它來優雅地解決一些以前難以處理的問題(通常,以前我們使用反射來解決這些麻煩),比如:

(1)“泛型參數類型是動態”,使用動態代理解決這種問題不僅可以避免反射帶來的效能損失,而且還可以獲得強型別方法調用的好處。

(2)為一群組類型“變臉”。比如,TextBox、RichTextBox、ListView等windows控制項都有Clear方法,但是它們都沒有實現一個統一的介面(比如,該介面中定義了Clear方法),所以當我要清空某個GroupBox中所有控制項的內容時,無法用一種統一的方式調用,你不能這樣做:

以下為引用的內容:
  foreach (Control control in this.groupBox1.Controls)
            {
                control.Clear(); //Control不存在Clear方法,編譯報錯
            }

但是有了動態代理之後,我們就可以為這些控制項定義一個New Face:

以下為引用的內容:

public interface INewFace
    {
        void Clear();
    }

然後優雅地這樣調用:

以下為引用的內容:

foreach (Control control in this.groupBox1.Controls)
     {
          INewFace face = DynamicTypeEmitter.CreateDynamicProxy<INewFace>(control);
          face.Clear();
     }

你可以繼續挖掘使用動態代理的其它場合,發揮你的想象力,來展現動態代理的威力。

關於ESBasic中的 DynamicTypeEmitter 實現,有一點缺憾,那就是暫時還不支援“泛型方法”的調用轉寄,我還不知道如何使用Emit發射對動態型別參數的泛型方法的調用,有知道的朋友請指導下。



相關文章

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。