1. 程式人生 > >Emit動態代理.NetCore遷移之旅

Emit動態代理.NetCore遷移之旅

兼容問題 www 地方 http 1.2 ron target targe 單元測試

【前言】

  前面我們介紹了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 即可;

Emit動態代理.NetCore遷移之旅