框架学习与探究之AOP--Castle DynamicProxy
前言
先說一點(diǎn)廢話,在此之前博主也在早期就接觸了或者看了些許AOP相關(guān)的文章,然后再去做了一些相關(guān)的實(shí)驗(yàn),但是始終沒有將AOP內(nèi)化到自己的內(nèi)功心法當(dāng)中去,包括從概念還是應(yīng)用環(huán)境,以及當(dāng)前生態(tài)當(dāng)中的AOP工具等等,所以這里博主還是按照以往的套路,在前人的基礎(chǔ)之上學(xué)習(xí)然后吸收到集成到系統(tǒng)當(dāng)中去。
什么是AOP
還是先看官方解釋:AOP(Aspect-Oriented Programming,面向切面的編程),它是可以通過預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)在不修改源代碼的情況下給程序動(dòng)態(tài)統(tǒng)一添加功能的一種技術(shù)。它是一種新的方法論,它是對(duì)傳統(tǒng)OOP編程的一種補(bǔ)充。OOP是關(guān)注將需求功能劃分為不同的并且相對(duì)獨(dú)立,封裝良好的類,并讓它們有著屬于自己的行為,依靠繼承和多態(tài)等來定義彼此的關(guān)系;AOP是希望能夠?qū)⑼ㄓ眯枨蠊δ軓牟幌嚓P(guān)的類當(dāng)中分離出來,能夠使得很多類共享一個(gè)行為,一旦發(fā)生變化,不必修改很多類,而只需要修改這個(gè)行為即可。AOP是使用切面(aspect)將橫切關(guān)注點(diǎn)模塊化,OOP是使用類將狀態(tài)和行為模塊化。在OOP的世界中,程序都是通過類和接口組織的,使用它們實(shí)現(xiàn)程序的核心業(yè)務(wù)邏輯是十分合適。但是對(duì)于實(shí)現(xiàn)橫切關(guān)注點(diǎn)(跨越應(yīng)用程序多個(gè)模塊的功能需求)則十分吃力,比如日志記錄,權(quán)限驗(yàn)證,異常攔截等。這里可以看到當(dāng)我們?cè)趹?yīng)用程序中使用AOP來編程的話,是大大的節(jié)約我的代碼量而且做到了職責(zé)依然分明,所以有這么多好處的情況下,我們就應(yīng)該勇敢的嘗試來構(gòu)建我的應(yīng)用程序...
.NET當(dāng)中的AOP
根據(jù)上文關(guān)于AOP的兩種方式來實(shí)現(xiàn)了面向切面編程,而在.NET領(lǐng)域當(dāng)中有些比較出名的,例如在動(dòng)態(tài)代理方面就是castle.core(原名:castle dynamic proxy)通過Reflect.Emit的方式在原始基礎(chǔ)上面實(shí)現(xiàn)的動(dòng)態(tài)代理方式,加上緩沖機(jī)制提升性能,該項(xiàng)目很好的屏蔽了底層使用emit+opcode的方式帶來的復(fù)雜性和難度,使用友好的API調(diào)用方式提供外部程序訪問(castle.coree nuget地址,小吐槽:.net core已經(jīng)2.0這么久了,castle家族雖然也還在努力,但是依然還沒支持.net standrad2.0,可能是因?yàn)閏astle.core現(xiàn)在打包了不止dynamicproxy一個(gè)包的原因,需要一些時(shí)間,不過在@Lemon努力下率先提供了基于.net core的aop框架,這里博主也是對(duì)此框架目前也是淺嘗輒止的狀態(tài)還沒有應(yīng)用到項(xiàng)目中,所以不好對(duì)比評(píng)價(jià)哈,哈哈!),所以基于我們當(dāng)前的項(xiàng)目而已動(dòng)態(tài)中的castle不失為我們的一個(gè)好的選擇;然后在.net靜態(tài)編織方面當(dāng)屬postsharp首當(dāng)其沖了,當(dāng)然這玩意兒是收費(fèi)不過你可以使用express免費(fèi)版但是和企業(yè)版對(duì)dll的修改差異就不得而知了,當(dāng)初博主實(shí)驗(yàn)安裝的企業(yè)版也是在免費(fèi)期內(nèi)使用后面做了一些小手腳才得以繼續(xù)使用,當(dāng)然這里不推薦破解使用了,有錢的主兒還是支持正版吧,注意使用postsharp需要vs安裝插件(需要插件支持才可以編譯后期對(duì)dll動(dòng)手腳)以及nuget package支持,所以團(tuán)隊(duì)里面如果使用需要大家統(tǒng)一安裝,還有就是目前許多都是基于Jenkins來做持續(xù)集成的,所以還得注意使用了postsharp的項(xiàng)目編譯問題(使用了postsharp如果沒有插件支持會(huì)報(bào)錯(cuò))!!,當(dāng)然我這里的指出相對(duì)比較計(jì)較的性能問題,靜態(tài)編織是比動(dòng)態(tài)代理來的更快,因?yàn)閐ll在編譯之后都已經(jīng)形成了AOP之勢(shì),動(dòng)態(tài)代理畢竟是運(yùn)行時(shí)才得以去構(gòu)建各種代理對(duì)象不過還好有緩沖,所以相對(duì)一般情況動(dòng)態(tài)代理足以滿足我們的需求,還是那個(gè)句話:在已經(jīng)解決顯而易見的瓶頸之后,才考慮一些錙銖必較的性能缺失!!!,最后.NET周邊其他AOP框架或者產(chǎn)品不管是動(dòng)態(tài)還是靜態(tài),大家可自行搜索是有的,不過使用率以及可用性、穩(wěn)定性、性能等等就不好說了!
Castle DynamicProxy文檔帶來了什么
首先Castle DynamicProxy是一個(gè)在運(yùn)行時(shí)即時(shí)生成輕量級(jí).NET代理的庫,然后除了介紹AOP使用場(chǎng)景就是當(dāng)前一些流行項(xiàng)目對(duì)于castle.core的依賴,側(cè)面也反應(yīng)除了此AOP的地位,好吧,233333,官方文檔是要捧一下自己的。我們會(huì)發(fā)現(xiàn)?moq(mock的實(shí)現(xiàn))、NHibernate(延遲加載virtual+getter攔截實(shí)現(xiàn)等)等都依賴了castle.core,說明了上面的框架功能提供肯定是需要?jiǎng)討B(tài)代理的支撐的,然后根據(jù)官方說明在版本2.5之后原先獨(dú)立的castle.dynamicproxy.dll就合并了,官方高能:如果您有一個(gè)長(zhǎng)時(shí)間運(yùn)行的進(jìn)程(網(wǎng)站,Windows服務(wù)等),并且必須創(chuàng)建許多動(dòng)態(tài)代理,那么您應(yīng)該確保重用相同的ProxyGenerator實(shí)例。如果沒有,請(qǐng)注意,您將繞過緩存機(jī)制,副作用是CPU使用率高,內(nèi)存消耗不斷增加。
這里引用官方對(duì)于catle dynamicproxy的工作原理及流程的理解,顯示給出執(zhí)行流程圖:
我們這里外部的藍(lán)色框就是代理區(qū)域,黃色箭頭將會(huì)層層進(jìn)入各級(jí)代理對(duì)象,接著代理執(zhí)行PreAction邏輯,然后調(diào)用invocation.Proceed()(每個(gè)代理只能調(diào)用一次不然出爆發(fā)異常)進(jìn)入下一個(gè)代理或者原始對(duì)象邏輯,就這樣一直進(jìn)入到最下層也就是被代理的對(duì)象,執(zhí)行原始邏輯之后,再按照層層代理執(zhí)行PostAction邏輯彈出也就是綠色箭頭所表達(dá)的意思,就是一條完成的傳遞鏈就形成了多級(jí)代理模式。注意點(diǎn):每一層代理對(duì)象都可以拿到目標(biāo)的對(duì)象也就是被代理對(duì)象IInvocation,該接口包含了一些重要屬性和方法,例如:invocation.MethodInfo、invocation.ResultValue 等對(duì)象,我們接下來對(duì)API實(shí)驗(yàn)詳細(xì)看看這些對(duì)象的真實(shí)面目,至此根據(jù)官方文檔就這樣沒了,還有些stackoverflow的參考代碼,我們同時(shí)翻看園中其他使用代碼和對(duì)API的探究完善對(duì)castle dynamicproxy的了解....
Castle DynmaicProxy API提供了什么
首先這里要說明框架當(dāng)中幾個(gè)重要的對(duì)象:
1、IInterceptor?攔截器,該接口提供了可以自定義攔截器邏輯的入口,實(shí)現(xiàn)接口的 Intercept 方法即可,在后面創(chuàng)建代理對(duì)象需要接口實(shí)例來控制代理對(duì)象行為,這里框架也提供了StandardInterceptor標(biāo)準(zhǔn)的攔截器繼承MarshalByRefObject對(duì)象以及實(shí)現(xiàn)了IInterceptor接口,它包含了protected virtual void PerformProceed(IInvocation invocation);protected virtual void PostProceed(IInvocation invocation);protected virtual void PreProceed(IInvocation invocation);三個(gè)常用的接口方法....
2、IProxyGenerator?代理對(duì)象的創(chuàng)建者,包含了兩個(gè)屬性:Logger?、ProxyBuilder(只讀,具體由它來創(chuàng)建代理類型),包含如下幾個(gè)重要的API方法:
(1)動(dòng)態(tài)創(chuàng)建類代理?proxyGenerator.CreateClassProxy 包含重載:Creates proxy object intercepting calls to virtual members of type TClass on newly created instance of that type with given interceptors. (創(chuàng)建一個(gè)新的代理對(duì)象subclass,通過配置的攔截器攔截原始對(duì)象標(biāo)記了公開public的虛方法virtual的method產(chǎn)生效果,包含使用方法傳遞進(jìn)來的代理配置項(xiàng));
(2)動(dòng)態(tài)創(chuàng)建類代理通過既有實(shí)例?proxyGenerator.CreateClassProxyWithTarget 包含重載:Creates proxy object intercepting calls to virtual members of type TClass on newly created instance of that type with given interceptors.(創(chuàng)建一個(gè)新的代理對(duì)象subclass,通過配置的攔截器攔截原始對(duì)象標(biāo)記了公開public的虛方法virtual的method產(chǎn)生效果,提供了方法參數(shù)傳遞一個(gè)既有的目標(biāo)實(shí)例對(duì)象,包含使用方法傳遞進(jìn)來的代理配置項(xiàng));
(3)動(dòng)態(tài)創(chuàng)建接口代理不需要實(shí)現(xiàn)接口的實(shí)例對(duì)象?proxyGenerator.CreateInterfaceProxyWithoutTarget:Creates proxy object intercepting calls to members of interface TInterface on target object generated at runtime with given interceptor.(動(dòng)態(tài)創(chuàng)建接口對(duì)象實(shí)現(xiàn)的實(shí)例且不需要實(shí)現(xiàn)了接口實(shí)例參數(shù),通過攔截器湊效于接口方法實(shí)現(xiàn)攔截,注意這里如果接口方法要求了返回值,就需要在攔截器中指定返回值,類似于:invocation.ReturnValue=2;)
(4)動(dòng)態(tài)創(chuàng)建接口代理通過實(shí)現(xiàn)接口的實(shí)例對(duì)象?proxyGenerator.CreateInterfaceProxyWithTarget:Creates proxy object intercepting calls to members of interface TInterface on target object with given interceptors.(動(dòng)態(tài)創(chuàng)建接口代理對(duì)象,通過傳遞實(shí)現(xiàn)了接口的對(duì)象實(shí)例,使用配置的攔截器對(duì)象作用于接口的每個(gè)方法,這里實(shí)現(xiàn)接口的對(duì)象實(shí)例的實(shí)現(xiàn)方法就可以不需要配置為vritual了,因?yàn)樵诮涌诖韺?duì)象中已經(jīng)包裹住了原始對(duì)象是采用了類似于注入的方式而不是繼承,可以參考下面的示例代碼)
(5)動(dòng)態(tài)創(chuàng)建接口代理通過實(shí)現(xiàn)了接口的實(shí)例對(duì)象?proxyGenerator.CreateInterfaceProxyWithTargetInterface:Creates proxy object intercepting calls to members of interface TInterface on target object with given interceptors. Interceptors can use Castle.DynamicProxy.IChangeProxyTarget interface to provide other target for method invocation than default target.(與上述CreateInterfaceProxyWithTarget相似,那么它們的區(qū)別在于哪里吶,這里博主本著研究的精神找了一下,不至于翻看源碼了....,找到類似代碼提供者的一點(diǎn)描述如下:http://kozmic.net/2009/11/13/interfaceproxywithtarget-interfaceproxywithtargetinterface-ndash-whatrsquos-the-difference/,大體總結(jié)就是:一般情況下調(diào)用者需要的就是CreateInterfaceProxyWithTargetInterface這個(gè)API的調(diào)用,其中它提供了兩個(gè)優(yōu)點(diǎn):當(dāng)使用InterfaceProxyWithTargetInterface時(shí),它的調(diào)用實(shí)現(xiàn)了IChangeProxyTarget接口,該接口允許攔截途中更改目標(biāo)對(duì)象。然后最重要的是 InterfaceProxyWithTargetInterface更好地使用緩存,詳情參考鏈接代碼驗(yàn)證過程,當(dāng)然博主也親自測(cè)試如同文中作者如出一轍!!。)博主實(shí)驗(yàn)參考如下:
關(guān)于castle dynamicproxy動(dòng)態(tài)代理中的對(duì)與class與interface的處理方式大致原理探究:關(guān)于class的代理,相信很多同學(xué)都應(yīng)該直到,也就是設(shè)計(jì)模式當(dāng)中的代理模式的利用,具體就是繼承原始類對(duì)象實(shí)現(xiàn)對(duì)原始對(duì)象虛方法的重寫實(shí)現(xiàn)注入攔截的邏輯,不過這一切都是動(dòng)態(tài)的不需要我們?nèi)?gòu)建了,參考代碼如下(這里只考慮一級(jí)代理,多級(jí)也就是多層繼承關(guān)系):
public class Caller{ ? ? ? ?public virtual void Call() ? ? ? ?{Console.WriteLine("calling...");}} ? ?public class CallerProxy : Caller{ ? ? ? ?public override void Call() ? ? ? ?{ ? ? ? ? ? ?// 執(zhí)行前Console.WriteLine("pre action"); ? ? ? ? ? ?base.Call(); ? ? ? ? ? ?// 執(zhí)行后Console.WriteLine("post action");}} ? ?static void Main(string[] args) ? ? ? ?{Caller caller = new CallerProxy();caller.Call(); Console.ReadKey();}接著關(guān)于interface的代理的大致原型是,通過實(shí)現(xiàn)接口產(chǎn)生一個(gè)包含了傳遞的接口實(shí)習(xí)實(shí)例對(duì)象的接口代理對(duì)象,可能這里有點(diǎn)繞,不過依然還是代理模式,關(guān)系從繼承變成了包含,同理這些東西castle已經(jīng)幫我用動(dòng)態(tài)的方式構(gòu)建好了,我們看一示例代碼就知道了,這里展示一層代理多級(jí)代理就是層層包含了:
public interface IService{ ? ? ? ?void Process();} ? ?public class Service : IService{ ? ? ? ?public void Process() ? ? ? ?{ ? ? ? ? ? ?// do somethingConsole.WriteLine("processing...");}} ? ?public class ServiceProxy : IService{ ? ? ? ?private readonly Service _service; ? ? ? ?public ServiceProxy(Service service) ? ? ? ?{_service = service;} ? ? ? ?public void Process() ? ? ? ?{ ? ? ? ? ? ?// pre actionConsole.WriteLine("pre action");_service.Process(); ? ? ? ? ? ?// post actionConsole.WriteLine("post action");}}IService service = new ServiceProxy(new Service());service.Process();Console.ReadKey(); 相信看到這里你也覺得,我去,動(dòng)態(tài)代理這么簡(jiǎn)單么,其實(shí)不然,雖然道理大家一看就懂是簡(jiǎn)單就是設(shè)計(jì)模式的代理模式的運(yùn)用嘛,但是將這個(gè)動(dòng)作泛化為一個(gè)通用的API支持可變攔截器數(shù)量配置以及各種代理配置將是一項(xiàng)繁雜而小心的工作,既要考慮友好的API還有重中之重的性能保證,也就是使用上面提到的 Reflect.Emit + OpCode 來實(shí)現(xiàn)接近于元數(shù)據(jù)編程....,可怕!!!所以,這里給寫AOP的同學(xué)點(diǎn)贊!@Lemon
3、代理生成配置對(duì)象?ProxyGenerationOptions,在生成代理對(duì)象是可傳遞自定義配置對(duì)象,實(shí)現(xiàn)可控的攔截,該對(duì)象主要配置項(xiàng):
public IProxyGenerationHook Hook { get; set; } (決定了該方法是否受攔截器攔截,可以實(shí)現(xiàn)自定義Hook)
public IInterceptorSelector Selector { get; set; } (決定了該方法受那些攔截器攔截,可以實(shí)現(xiàn)自定義Selector)
public Type BaseTypeForInterfaceProxy { get; set; } (決定了接口代理的基礎(chǔ)類型,詳情使用參考鏈接:https://stackoverflow.com/questions/2969274/castle-dynamicproxy-how-to-proxy-equals-when-proxying-an-interface)
具體例子參考如下:
這里相信大家一看就明白了,就不多說了.....這里注意點(diǎn)就是:?攔截器的植入順序與生效順序是一致的....
從其他框架復(fù)盤認(rèn)識(shí)castle與集成
了解過[abp]:(https://aspnetboilerplate.com/) 的同學(xué),肯定就知道此框架強(qiáng)制把castle家族的castle.core+Castle.Windsor(依賴前者)融入進(jìn)abp當(dāng)中了,采用了接口代理實(shí)現(xiàn)了日志記錄、異常處理、權(quán)限審查、審計(jì)日志等等,當(dāng)然abp框架當(dāng)中確實(shí)不止一處是值得我們學(xué)習(xí),不過此框架構(gòu)建在一個(gè)及集眾家之所長(zhǎng)的情況下就顯得復(fù)雜,從知名度可以看出選擇caslte來作為aop+ioc的集成是個(gè)不錯(cuò)的選擇,接著從moq的部分實(shí)例代碼中可以看出,就是利用了proxyGenerator.CreateInterfaceProxyWithoutTarget等等,之類的細(xì)節(jié)就可以回想起原始API做起底層的支撐作用,再者castle與許多第三方ioc有著比較好的集成,例如比較出名的ioc框架autofac+castle也是很多人的選擇,參考鏈接:[AOP系列]Autofac+Castle實(shí)現(xiàn)AOP事務(wù):http://www.cnblogs.com/jianxuanbing/p/7199457.html
這里博主為何要把ioc扯進(jìn)來一起說吶?
從castle的api來看大家覺得有木有點(diǎn)覺著好像有著一點(diǎn)ioc的功能,但是為何我們要明確概念說aop是aop,ioc是ioc吶,這里博主的理解就是,它們各自的職責(zé)是不同,它們各自只需要各司其職就行了,也不要越界也是編程開發(fā)當(dāng)中的單一職責(zé)的體現(xiàn)了,雖然多多少少大家都有些動(dòng)態(tài)創(chuàng)建對(duì)象那么回事兒(不管是emit還是activor.CreateInstance)!但是我們從ioc的職能分析得到的是:1、負(fù)責(zé)對(duì)象的存儲(chǔ)(注冊(cè))與創(chuàng)建(解析) 2、負(fù)責(zé)對(duì)象的依賴關(guān)系維護(hù) 3、負(fù)責(zé)對(duì)象的生命周期,這三點(diǎn)就可以看出與AOP功能不一致,但是我們看到對(duì)象創(chuàng)建這個(gè)時(shí)候,想一下是否可以在對(duì)象創(chuàng)建的時(shí)植入Interceptor???回答是:肯定是可以的,所以這就是為何我們常常把ioc與aop一起來食用了,聽說這樣用更配哦!!
總結(jié)
我們從AOP的定義到AOP的使用場(chǎng)景,然后.net下面的AOP的介紹,接著重點(diǎn)介紹了動(dòng)態(tài)代理中的castle.core的官方說明與文檔,后面尤其重要的詳解了框架當(dāng)中重要的一些對(duì)象和API以及原理和實(shí)踐,也途中參考一些文章和stackoverflow,也請(qǐng)教AOP相關(guān)人士,這里感謝!好了,時(shí)間也不早了,相信學(xué)無止境,那么就保持持續(xù)學(xué)習(xí),持續(xù)內(nèi)化知識(shí),就像修煉內(nèi)功心法一樣,半途而廢還容易走火入魔,一知半解說出去的東西自己都沒搞明白,豈不是笑話了!!加油吧,騷年
這里引用知乎大大的一段話以此激勵(lì):成長(zhǎng)必須經(jīng)歷一個(gè)步驟,就是把知識(shí)內(nèi)化成能力。知識(shí)是用腦記住的,能力是用手練習(xí)出來的。在工作的幾年里,我們可能看過很多書,聽過很多技術(shù)講座和視頻,但是通過聽和看只是讓你能記住這些知識(shí),這些知識(shí)還不能轉(zhuǎn)換成你的能力。聽和看只是第一步,更重要的是實(shí)踐,通過刻意練習(xí)把聽到和看到的知識(shí)內(nèi)化成你的能力。刻意練習(xí),就是有目的的練習(xí),先規(guī)劃好,再去練習(xí)。首先給自己定一個(gè)目標(biāo),目標(biāo)可以有效的引導(dǎo)你學(xué)習(xí),然后使用3F練習(xí)法:1: 專注(Focus),專注在眼前的任務(wù)上,在學(xué)習(xí)過程中保持專注,可以嘗試使用番茄工作法。2:反饋(Feedback),意識(shí)到自己的不足,學(xué)習(xí)完之后進(jìn)行反思,思考下自己哪些方面不足,為什么不足,3: 修正(Fix),改進(jìn)自己的不足。不停的練習(xí)和思考可以改變大腦結(jié)構(gòu),大腦像肌肉一樣,挑戰(zhàn)越大,影響越大,學(xué)習(xí)更高效,并且也會(huì)產(chǎn)生突破性。?-- 原始鏈接:?https://www.zhihu.com/question/26572626/answer/246901769?utm_medium=social&utm_source=qq
收集備注園中相關(guān)AOP好文
1、Asp.Net Core輕量級(jí)Aop解決方案:AspectCore?http://www.cnblogs.com/liuhaoyang/p/aspectcore-introduction-1.html
2、C# 實(shí)現(xiàn)AOP 的幾種常見方式?:?http://www.cnblogs.com/zuowj/p/7501896.html
3、.Net基于RealProxy實(shí)現(xiàn)AOP?:?http://www.cnblogs.com/lflyq/p/6286925.html
4、Aspect-Oriented Programming : 使用 RealProxy 類進(jìn)行面向方面的編程?:?https://msdn.microsoft.com/zh-cn/magazine/dn574804.aspx
補(bǔ)充更新(2017年10月20日15:07:33)
關(guān)于 castle api 當(dāng)中對(duì)于?IInvocation對(duì)象的解釋少了一些,這里補(bǔ)充一下:
1、invocation.Arguments: 方法執(zhí)行被攔截時(shí)的方法參數(shù)數(shù)組
2、invocation.GenericArguments: 被攔截方法的泛型參數(shù)類型數(shù)組,如果沒有就是null
3、invocation.InvocationTarget: 獲取當(dāng)前執(zhí)行的目標(biāo)對(duì)象,例如:如果是class代理就是YourClassProxy,接口代理就是實(shí)現(xiàn)接口的對(duì)象實(shí)例,如果沒有則為null,也就是當(dāng)使用xxxWithoutTarget的時(shí)候
4、invocation.Method:獲取代理對(duì)象的方法信息,例如:如果是class代理的時(shí)候就是YourClass.YourMethod對(duì)象的MethodInfo且這個(gè)時(shí)候invocation.Method == invocation.MethodInvocationTarget;如果是interface代理就是接口對(duì)象的方法信息,例如:ICall.Call 這個(gè)方法的MethodInfo信息且這個(gè)時(shí)候invocation.Method != invocation.MethodInvocationTarget,因?yàn)閕nvocation.MethodInvocationTarget是接口對(duì)應(yīng)實(shí)現(xiàn)的目標(biāo)對(duì)象的方法信息,也就是例如:MyCall.Call 方法對(duì)應(yīng)上面的 ICall 接口來說,當(dāng)然也可以使用 WithoutTarget方式,這樣就會(huì)導(dǎo)致?invocation.MethodInvocationTarget==null的情況
5、invocation.MethodInvocationTarget: 指向真正的目標(biāo)對(duì)象的方法信息MethodInfo,大致可以根據(jù)第四點(diǎn)給出了說明
6、invocation.Proxy?: 獲取攔截時(shí)的代理對(duì)象,例如:YourClassProxy(類代理) 或者 ICallProxy(接口代理) 對(duì)象
7、invocation.ResultValue: 獲取或者設(shè)置代理方法的返回值
8、invocation.TargetType: 獲取真實(shí)目標(biāo)對(duì)象的類型
9、invocation.GetArgumentValue(int index);: 通過index獲取參數(shù)值
10、invocation.GetConcreteMethod();: 同理第四點(diǎn)
11、invocation.GetConcreteMethodInvocationTarget();: 同理第五點(diǎn)
12、invocation.Proceed();: 調(diào)用下一個(gè)攔截器直到目標(biāo)方法
13、invocation.SetArgumentValue(int index, object value);: 設(shè)置更改參數(shù)值通過下標(biāo)
這里博主列舉除了攔截途中對(duì)象IInvocation的所有成員,大家在使用攔截器的時(shí)候可根據(jù)自己邏輯使用以上API到達(dá)要求!
原文地址:http://www.cnblogs.com/DjlNet/p/7603654.html
.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺(tái)或掃描二維碼關(guān)注
總結(jié)
以上是生活随笔為你收集整理的框架学习与探究之AOP--Castle DynamicProxy的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [译]ASP.NET Core 2.0
- 下一篇: Visual Studio 15.5预览