Emit動態代理.NetCore遷移之旅

【前言】

  前面咱們介紹了Aop 從靜態代理到動態代理:http://www.javashuo.com/article/p-tkikwfqg-ew.htmlhtml

  咱們在.NetFramework平臺下使用微軟提供的Emit技術實現了動態代理類的生成。可是.NetCore做爲微軟.Net平臺的春天,若是類庫光支持.NetFramework,那麼未免有種沒有跟上時代步伐的感受,那麼,咱們就趕忙在.NetCore平臺也實現一套吧。git

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

【開始遷移】

  爲了達到類庫跨平臺的目的,咱們新建一個.NetStandard類庫,選擇什麼版本呢?單元測試

  

  爲了兼容目前不少老舊的項目,咱們看到 .NetStandard1.2最低支持.Net Framwork 4.5。爲了保持兼容性,先建一個.Net Standard 1.2版本的類庫。測試

  代碼複製過來,坑以下:ui

  

  1.Attribute的獲取方法不支持

  

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

  

  

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

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

  

  若是咱們要使用Emit這個特性的話,咱們須要引用Nuget  System.Reflection.Emit,全部的Emit特性代碼都包含在這個組件中。spa

   ...3d

  

  一整鼓搗以後,爲何還有代碼在報紅字...代理

  

  

  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 便可;

相關文章
相關標籤/搜索