Emit動態代理.NetCore遷移之旅


【前言】

  前面我們介紹了Aop 從靜態代理到動態代理:https://www.cnblogs.com/7tiny/p/9657451.html

  我們在.NetFramework平台下使用微軟提供的Emit技術實現了動態代理類的生成。但是.NetCore作為微軟.Net平台的春天,如果類庫光支持.NetFramework,那么未免有種沒有跟上時代步伐的感覺,那么,我們就趕緊在.NetCore平台也實現一套吧。

  本想着新建一個.NetStandard項目,代碼復制過來就直接能用的,沒想到:一路坎坷...

【開始遷移】

  為了達到類庫跨平台的目的,我們新建一個.NetStandard類庫,選擇什么版本呢?

  

  為了兼容目前很多老舊的項目,我們看到 .NetStandard1.2最低支持.Net Framwork 4.5。為了保持兼容性,先建一個.Net Standard 1.2版本的類庫。

  代碼復制過來,坑如下:

  

  1.Attribute的獲取方法不支持

  

  2.Reflection 反射 GetMethods方法不支持,BindingFlags不支持(版本太低,Api沒有全部實現)

  

  

  萬般無奈之下,舍棄了兼容性,保證了代碼的遷移。最終將我們的.Net Standard 項目升級到了Api比較完善的2.0版本。

  3..Net Standard/Core平台將以往的系統類庫做了精簡,曾經在System命名空間下的很多代碼已經遷移到了單獨的Nuget包中。

  

  如果我們要使用Emit這個特性的話,我們需要引用Nuget  System.Reflection.Emit,所有的Emit特性代碼都包含在這個組件中。

   ...

  

  一整鼓搗之后,為什么還有代碼在報紅字...

  

  

  4.舊版不兼容(有的方法已被直接移除)

  這幾個方法經過嘗試,發現引用/更新程序集是解決不了的。上微軟官方文檔,居然發現這幾個方法已經打上了過期標簽。那么替代的方法呢?微軟的官方文檔里面並沒有說明。最終通過一頓搜索,在stackoverflow了解到了.NetCore下的替代方法:

  

  

  以前的Domain(應用程序域)定義程序集的方法已經遷移到了AssemblyBuilderAccess(程序集訪問)類中,雖然這個歸類更加合理了,但是一言不合就不兼容是不有點讓人吐槽啊...

  5.程序集不支持輸出到目錄

  

  .NetCore 平台已經不支持直接輸出到目錄,僅僅可以在內存中Run。

  6.typeBuilder類中的CreateType()方法消失

  

  CreateType()方法已經被直接移除掉了,官方解釋是統一使用他的子類。這個答案最終通過搜索引擎在GitHub上找到了

  https://github.com/dotnet/coreclr/issues/2222

  上面的鏈接是GitHub中 dotnet/coreclr 微軟官方項目中的Issue

  

  在其中可以看到我們遇到的很多坑在這里都有解釋說明,而且表明了最新的使用方案:

  

  於是乎,就用Type的子類TypeInfo類了唄,CreateTypeInfo()

【終於不報錯了】

  在解決完畢所有的遷移兼容問題后,我們還是上次文章中的所有單元測試流程。

  

  單元測試沒有問題,我們本次的 .NetCore 平台代碼遷移終於完成。

【總結】

  1. Emit動態代理.NetStandard2.0 最低支持意味着支持.Net Core2.0/.Net Framework 4.6.1以上;
  2. 微軟在Api的遷移中,對部分代碼進行了重新的歸類,但是很多地方對舊版本不兼容我,切沒有替換的官方文檔;
  3. .Net Core 平台對系統類庫進行了精簡,移除了不必要的很多類庫,需要使用的時候,通過對應的Nuget進行引用,但是沒看到官方清單;

  最終結果是遷移完畢,新的項目命名為 SevenTiny.Bantina.Aop 吧,也算一個基礎組件

  項目地址:https://github.com/sevenTiny/SevenTiny.Bantina

  如果想直接引用Nuget使用的,已經構建好了,Nuget包搜索 SevenTiny.Bantina.Aop 即可;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM