.Net Standard擴展支持實例分享

  上篇(.Net基礎體系和跨框架開發普及)介紹了.Net當前生態下的大概狀況,也分享了簡單實現的過程,這篇文章就是講解個人OSS.Common項目擴展.Net Standard 支持的過程,主要集中在:方案的選擇,移植檢測,移植過程,常見問題的解決思路,以及nuget的打包部署這幾個方面。html

  在開始以前簡單介紹下OSS.Common項目的涉及的內容,方便了解後邊所遇到的問題。這個類庫是相對簡單的一個基礎類庫,提供主要有如下的內容:1. 基礎用戶系統設備信息實體定義,2. 主流加解密方案實現(md5,aes,sha1,hmacsha1), 3.  常規實體DTO轉化,靜態擴展方法(時間,字符串等等處理), 4. 基礎日誌,緩存,異步輔助靜態類及默認方案實現(採用了簡單Provider模式,使用者能夠註冊本身的實現方案), 5. 全局結果,分頁實體定義。  其主要做用就是完成對常見碎化方法的收集規整,方便在業務邏輯中減小沒必要要的消耗,瞭解以後咱們進入具體的擴展過程。git

  一. 方案的選擇github

  這個其實在上篇文章中已經作了介紹,當前.net core ,.net Framework,mono for Xarmain等都有本身的運行時,雖然使用的都是C#語法,可是類庫在不使用可移植或者標準庫的前提下不能直接互相調用。隨着.net standard 2.0的即將推出,.net core(asp.net core) 的應用場景會愈來愈廣泛,對舊有項目的兼容需求會愈來愈強烈,oss.common也是遇到這個問題,因此我將對它進行.net standard支持的擴展。算法

  因爲當前項目如今在好幾個.net framework的項目中還在使用,爲了舊項目中對net45的版本的支持不能丟失,因此我會保留兩套解決方案,一個爲.net Standard 提供支持,一個爲.net framework使用,兩個類庫項目,共享同一套代碼文件,針對Framework特有功能經過條件編譯來控制。github上目錄結構已更新,歡迎查看json

  二. 移植檢測api

  在移植以前咱們須要對移植有個大概評估,瞭解須要代碼改動的覆蓋面積,肯定代碼的可移植性,這裏推薦使用微軟官方提供的移植檢測工具(ApiPort),或者使用它的VS擴展。這裏我使用的是vs插件,安裝完插件以後,打開解決方案,查看右鍵菜單會有以下兩個選項:緩存

  首先,點擊第二個選項,配置要檢測的移植對比版本,以下圖:框架

  完成對應的檢測版本以後點擊肯定,點擊第一個選項,執行分析過程,會生成html和xsl兩種報表,html報表界面以下所示:asp.net

 報表中會給出對應版本的接口覆蓋狀況,以及相關的建議,能夠說是比較詳細了。異步

  三.移植過程

  通過上邊的檢測,能夠看出oss.common項目 在.net standard1.4下,大概超過20%的代碼不能直接提供支持,我看了一下,主要集中在涉及配置,緩存,反射等特有屬性相關代碼中,這個還算在預期之中,不過看到一堆的紅叉叉仍是一陣頭疼,沒辦法,本身的類庫,哭着也要碼完,下邊介紹下移植的步驟。

  1. 添加項目文件

  爲了項目直觀和方便管理,我將原來的OSS.Common類庫修更名稱爲OSS.Common.NET45,新建一個OSS.Common的標準庫項目,兩個項目文件放在同一目錄下,說明一下,vs2015若是要建標準庫項目須要先建可移植類庫,在類庫屬性頁修改,若是不清楚請看上一篇文章介紹。

  這個時候若是你直接生成OSS.Common.NET45的項目,是會出現報錯的,哪怕你沒有作任何實際的代碼的操做,主要是由於添加可移植類庫須要project.json的文件進行依賴管理,當他們在同一目錄下時,nuget會把project.json中的依賴默認執行還原操做,雖然你當前是在生成OSS.Common.NET45項目,沒辦法,就是這麼傻,若是你遇到了這個錯誤,在當前目錄中再建一個對應當前項目文件的project.json文件就行了,這裏我添加了OSS.Common.Net45.project.json文件,文件中添加以下代碼:

{
"frameworks": {
"net45": {}
},
"runtimes": {
"win": {}
}
}

 

  2. 代碼集成

  新建好對應的解決方案以後,把代碼文件附件到新建的標準庫下,這個時候直接生成會有不少錯誤,這個時候咱們就須要祭出條件編譯這個大招了,由於之後主要是維護標準庫,因此我在舊NET45的舊項目上新建了NETFW的條件編譯符號 ,剩下的就是一個個錯誤完善了。

  在處理兼容的過程當中,主要會面臨這幾個問題,1. 標準庫徹底不支持   2.  標準庫和Framework的調用方法不同, 3. 能夠間接完成標準庫的實現

  這裏我把我遇到的狀況各舉一個例子供你們參考:

  1.  標準庫徹底不支持,這個最典型的就是緩存模塊,在.net standard下,System.Runtime.Caching類庫徹底被移除了,沒辦法,只能使用#if NETFW 徹底把Module模塊下的默認Cache實現給屏蔽了,只能在Framework下才能使用默認實現(原本打算本身實現一個緩存類的,不過發現可能會帶來不可預知bug,做廢)。

  2. 標準庫和Framework的調用方法不同,舉個例子就是Type類型下的IsEnum屬性,在net standard下須要.gettypeinfo().IsEnum才能夠,舉例代碼:

#if NETFW
if (!enType.IsEnum)
#else
if (!enType.GetTypeInfo().IsEnum)
#endif

  3. 能夠間接完成標準庫的實現,這常見的如 list的ConvertAll方法,在Framework下有默認實現的,標準庫下是沒有的,這裏我在ConvertExtention類本身定義了個一個:

#if !NET40
public static List<TResult> ConvertAll<TPara, TResult>(this List<TPara> list, Func<TPara, TResult> func)
{
if (list == null)
return null;
var resultList = new List<TResult>(list.Count);
list.ForEach(e => resultList.Add(func(e)));
return resultList;
}
#endif

 固然還會有其餘的一些問題,不過還好,基本都已經解決,若是有不清楚的能夠去下載oss.common代碼自行查看

 

  四. nuget打包部署

  這個相對簡單,在兩個解決方案中分別生成對應的dll,在lib文件夾中分別添加net45 和 netstandard1.4 文件夾添加對應的dll就行。

須要注意的一點就是,最好添加個各自的依賴,舉個例子,標準庫的Hmacsha1加密算法在「System.Security.Cryptography.Algorithms」 dll程序集下,若是在調用項目中沒有引用這個dll,生成是不會報錯的,可是當代碼執行調用的時候就會彈出程序集未找到的錯誤,固然若是發現這個問題也能夠經過nuget線上安裝命令(install-package)安裝。

  給你們看下個人nuget文件配置:

 

若有其它疑問,歡迎關注公衆號(osscoder):

相關文章
相關標籤/搜索