日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

【复杂系统迁移 .NET Core平台系列】之迁移项目工程

發(fā)布時(shí)間:2023/12/4 windows 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【复杂系统迁移 .NET Core平台系列】之迁移项目工程 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

源寶導(dǎo)讀:微軟跨平臺(tái)技術(shù)框架—.NET Core已經(jīng)日趨成熟,已經(jīng)具備了支撐大型系統(tǒng)穩(wěn)定運(yùn)行的條件。本文將介紹明源云ERP平臺(tái)從.NET Framework向.NET Core遷移過(guò)程中的實(shí)踐經(jīng)驗(yàn)。

一、背景

? ??隨著ERP的產(chǎn)品線越來(lái)越多,業(yè)務(wù)關(guān)聯(lián)也日益復(fù)雜,應(yīng)用間依賴關(guān)系也變得錯(cuò)綜復(fù)雜,單體架構(gòu)的弱點(diǎn)日趨明顯。19年初,平臺(tái)底層支持了分應(yīng)用部署模式,將ERP從應(yīng)用子系統(tǒng)層面進(jìn)行了切割分離,邁出了從單體架構(gòu)向微服務(wù)架構(gòu)轉(zhuǎn)型的堅(jiān)實(shí)一步。不久的將來(lái),ERP會(huì)進(jìn)一步將各業(yè)務(wù)拆分成眾多的微服務(wù),而微服務(wù)勢(shì)必需要進(jìn)行容器化部署和運(yùn)行管理,這就要求ERP技術(shù)底層必須支持跨平臺(tái),所以將現(xiàn)有ERP系統(tǒng)從.NET Framework遷移到 .NET Core平臺(tái)勢(shì)在必行。

二、遇到的問(wèn)題和應(yīng)對(duì)策略

? ? ERP在從Framework遷移到Core的時(shí)候主要要解決以下問(wèn)題:

  • 代碼文件和工程遷移。

  • Aspx文件遷移到Razor。

  • HttpModule和HttpHandler遷移。

  • ClownFish的Mvc機(jī)制遷移到Asp.Net Core MVC。

  • 其他一些Windows平臺(tái)Api遷移到跨平臺(tái)。

  • 發(fā)布和Docker部署。

  • ? ? 以上每個(gè)主題中都包含了大量的技術(shù)細(xì)節(jié),我們后面將陸續(xù)發(fā)文章分享經(jīng)驗(yàn)。本文先介紹關(guān)于項(xiàng)目工程遷移方面的內(nèi)容,具體的遷移步驟如下:

  • dll引用實(shí)際是一個(gè)層級(jí)關(guān)系,從啟動(dòng)項(xiàng)目往下找是可以找到一個(gè)最底層的依賴的,然后會(huì)存在一個(gè)依賴順序(拓?fù)渑判?,我們改造的時(shí)候也是從最底層開始改造起,逐個(gè)工程這樣遷移,遷移過(guò)程保證編譯通過(guò)。

  • 在類庫(kù)遷移的時(shí)候核心有三個(gè)點(diǎn),cs文件遷移,新的工程(.csproj)文件組織,dll引用組織。

  • 在站點(diǎn)項(xiàng)目遷移的時(shí)候需要考慮靜態(tài)資源(js,css等)的組織。

  • 在做完這些之后要考慮dll版本和最終打包發(fā)布。

  • 三、遷移代碼文件

    ? ? .NET Framework 的 .csproj 文件極其龐大且難以理解,在新的.Net Core中推出了全新的的.csproj組織方式。新的工程文件主要有如下優(yōu)勢(shì):

    • 在版本管理中更容易解決沖突:新方式包含了目錄下所有文件,老方式是需要顯示的引用(有點(diǎn)像黑名單和白名單的意思),這樣聲明的文件變得更少,從而減少了多人協(xié)作時(shí)XML合并沖突的風(fēng)險(xiǎn)。

    • 可以指定多個(gè)開發(fā)框架,提供更好的兼容性:以往如果要同時(shí)兼容.Net3.5和.Net 4.5的話需要建兩個(gè)工程,通過(guò)文件鏈接來(lái)處理多個(gè)框架兼容的問(wèn)題,新的組織方式一個(gè)工程文件即可處理。

    • 引用更加簡(jiǎn)潔:沒(méi)有對(duì)其他項(xiàng)目的基于GUID的引用,這可以提高文件的可讀性。同時(shí)基于NuGet的引用和路徑無(wú)關(guān),意味著可以指定任意的NuGet包的位置。

    • 嵌套的引用不需要重復(fù)指定(如果 A 引用了 B,B 引用了 C;那么 A 不需要顯式引用 C 也能調(diào)用到 C)。

    ? ? 項(xiàng)目遷移就是要實(shí)現(xiàn)對(duì)原來(lái).cs代碼進(jìn)行遷移,實(shí)現(xiàn)邏輯的復(fù)用,這里有三種遷移代碼文件的方式:

    1、Copy文件: 將原有的文件復(fù)制復(fù)制到新文件夾重新組織(基本相當(dāng)于重新寫一套就不贅述了)。

    2、文件鏈接: 使用文件鏈接只需新建一個(gè)工程使用來(lái)組織代碼,基于Framework和Core可以分別再額外添加文件,下面是示例:

    3、多框架:一個(gè)工程文件中有多個(gè)框架,下面是示例:

    ? ? 我們的策略是,根據(jù)不同的情況使用不同的遷移方式:

  • 對(duì)于基礎(chǔ)平臺(tái),由于是ERP的基礎(chǔ)底座,必須保證其遷移后的穩(wěn)定和兼容,但基礎(chǔ)平臺(tái)的代碼量大,功能多,如果僅靠大量測(cè)試很難保證整體遷移的質(zhì)量。由于Core和Framework的Api的一些差異,并不是完全兼容,但微軟還是提供了最大限度地功能兼容。為了以最低成本保障遷移質(zhì)量,最終我們采用的是文件鏈接的遷移方式

  • 對(duì)于平臺(tái)的文檔服務(wù)和配置中心,功能較簡(jiǎn)單,全面進(jìn)行回歸測(cè)試的成本不大,所以我們采用了多框架的遷移方式。雖然.NET Core在HTTP框架方面并不兼容,我們需要重寫個(gè)別項(xiàng)目,這些項(xiàng)目的代碼量不大,所以對(duì)遷移質(zhì)量的影響不大。

  • 對(duì)于平臺(tái)的調(diào)度服務(wù),我們采用重寫加上多框架的遷移方式。只是因?yàn)檎{(diào)度服務(wù)的核心引擎比較簡(jiǎn)單,我們直接采用重寫的遷移方式,這部分后面將會(huì)有單獨(dú)的文章來(lái)介紹。

  • 四、處理代碼文件兼容

    ? ? 當(dāng)我們解決了工程層面的兼容之后,引入的文件編譯肯定會(huì)報(bào)錯(cuò),解決這個(gè)問(wèn)題這個(gè)最核心的其實(shí)就是條件編譯了,示例如下:

    ? ? 雖然可以使用上述手段適配不兼容的API調(diào)用,但如果某個(gè)API被用到的地方特別多,就會(huì)出現(xiàn)大量重復(fù)的條件編譯,面對(duì)這個(gè)問(wèn)題,我們可以將調(diào)用API這部分代碼抽離成單獨(dú)的Helper類。舉個(gè)例子:在Framework和Core中,從Http上下文中取參數(shù)的方法存在很大差異,而之前代碼中大量調(diào)用了這個(gè)API方法,我們可以將調(diào)用此API的代碼封裝到一個(gè)單獨(dú)的Helper類,如下代碼所示:

    ? ? 上述示例中有如下幾點(diǎn)比較重要:

    • 命名空間中使用重命名的方式提供了參數(shù)的兼容使調(diào)用方代碼統(tǒng)一。

    • AsBase這類空方法提供了調(diào)用代碼的統(tǒng)一。

    • 在方法級(jí)別使用了條件編譯,結(jié)合后續(xù)的處理邏輯兼容提供了調(diào)用方代碼統(tǒng)一。

    • 在方法內(nèi)部使用了條件編譯,直接提供了方法調(diào)用的兼容。

    ? ? 在命名空間重命名的技巧中還有另外一個(gè)用法也特別有用,還是舉例說(shuō)明:

    ? ? 對(duì)比上述代碼可以發(fā)現(xiàn),使用占位Attribute的方式代碼會(huì)簡(jiǎn)潔很多,還有類似很多技巧這里就不一一說(shuō)明。

    ? ? 改造過(guò)程中總結(jié)出以下實(shí)踐:

  • 先用最簡(jiǎn)單的條件編譯。

  • 一個(gè)類里面方法和參數(shù)的特性導(dǎo)致重復(fù)的條件編譯比較多,考慮在命名空間部分使用重命名。

  • 一個(gè)類里面方法內(nèi)部重復(fù)的條件編譯比較多,考慮用類中私有方法來(lái)封裝這部分重復(fù)邏輯。

  • 多個(gè)類里面方法內(nèi)部重復(fù)的條件編譯比較多,考慮用用Helper類來(lái)封裝。

  • 如果是方案級(jí)別的不一樣,考慮用一個(gè)接口在Framework和Core中不同的實(shí)現(xiàn)來(lái)處理。

  • 五、處理包引用

    ? ??在處理完代碼層面兼容之后,還要處理第三方類庫(kù)的引用的問(wèn)題。我們先通過(guò)下面兩張圖看看Framework和Core中引用的不同。

    Framework引用關(guān)系:

    Core引用關(guān)系:

    ? ? 在Framework中都是平鋪的,而在Core中引用是樹形結(jié)構(gòu);比如在Framework中A引用了B,B引用C,A如果要用到C的功能就必須要顯式的引用C,但是在CoreA是不需要引用C的。所以我們改造的時(shí)候遵循從底層網(wǎng)上改,如果底層引用的包上層就不再引用,這樣大大減少了項(xiàng)目中包引用的數(shù)量。新的引用機(jī)制也帶來(lái)了一些問(wèn)題:

  • 平臺(tái)周邊的類庫(kù)文件,如果按照原來(lái)方式是需要打包兩個(gè)dll,然后手動(dòng)添加dll引用,這樣使倉(cāng)庫(kù)體積變大,同時(shí)也不容易維護(hù)版本。

  • 由于.Net Core的模塊化更細(xì),一個(gè)包可能依賴于很多的其他包,這樣就導(dǎo)致了拉取nuget包很慢。

  • ? ? 基于上述問(wèn)題我們引入了Nexus作為我們的包管理工具。通過(guò)這個(gè)工具可以將自己的類庫(kù)推送到自己的NuGet倉(cāng)庫(kù)管理,它同時(shí)還提供了代理的功能可以將遠(yuǎn)程的包存儲(chǔ)到局域網(wǎng),大大提高了拉包的速度。可能有些同學(xué)沒(méi)有使用過(guò)Nexus,這里做一個(gè)簡(jiǎn)單的介紹:

    • 功能: 提供的包類型非常豐富,支持nuget,maven,docker,npm,pypl,yum等,幾乎覆蓋市面所有流行的語(yǔ)言和工具。

    • Host倉(cāng)庫(kù): 支持自建倉(cāng)庫(kù)可以上傳自己制作的包并共享出來(lái)。

    • Proxy倉(cāng)庫(kù): 支持為其他遠(yuǎn)程倉(cāng)庫(kù)地址代理,通過(guò)代理可以將其他網(wǎng)站的軟件包緩存到本地,大大提高拉包的效率。

    • Group倉(cāng)庫(kù): 支持分組將多個(gè)代理和私服打包成一個(gè)組,這樣遠(yuǎn)程包的地址集中管理。

    • 權(quán)限管理:在任意一個(gè)倉(cāng)庫(kù)都可以控制增刪改查等權(quán)限。

    • 總之:還有更多功能大家可以去試試(強(qiáng)烈推薦)。

    六、處理靜態(tài)文件復(fù)用

    ? ??我們解決了類庫(kù)的遷移之后,由于在.NetCore改造過(guò)程中完全不涉及到前端js,css等文件的改造,所以要保證的js和css可以復(fù)用。在Framework中所有的資源文件都是相對(duì)于站點(diǎn)根目錄的路徑,而在Core中所有的資源文件都是在根目錄的wwwroot中,而在Core中提供了WebRootPath可以指定資源文件的路徑,我們?cè)趩?dòng)過(guò)程中做了如下配置:

    ? ? .Net Core中可以根據(jù)環(huán)境變量來(lái)加載不同的配置文件,首先會(huì)默認(rèn)加載appsettings.json,在開發(fā)環(huán)境中會(huì)額外的加載 appsettings.Development.json文件,后添加文件的配置項(xiàng)會(huì)覆蓋先添加文件的相同配置項(xiàng),這樣在生產(chǎn)環(huán)境中使用默認(rèn)的WebRootPath配置,而在開發(fā)環(huán)境中把WebRootPath指向原來(lái)Framework站點(diǎn)路徑,即可實(shí)現(xiàn)開發(fā)環(huán)境和生產(chǎn)環(huán)境的資源文件復(fù)用。

    七、處理dll版本迭代

    ? ? 在ERP發(fā)布過(guò)程中是需要管理版本的,每個(gè)dll的版本都應(yīng)該保持一致,那么就會(huì)涉及到如何通過(guò)修改一個(gè)地方讓所有dll版本都升級(jí)。

    • 在Framework中我們用到了兩種方法:

  • Assembly文件鏈接,在周邊服務(wù)中Assembly中不需要有太多信息,這個(gè)時(shí)候通過(guò)一個(gè)只有版本信息的Assembly文件然后通過(guò)文件鏈接方式加入到各個(gè)工程中,發(fā)布時(shí)候只需修改一個(gè)Assembly的版本號(hào)即可。

  • 老版本target文件引用,在每個(gè)工程中引入如下target文件,然后發(fā)布時(shí)候修改VersionAssembly中版本號(hào)即可。

    • 在Core中我們采用引入props文件(和target文件類似) ,使用方式如下所示:

    • ? ? 在Core中通過(guò)引入props文件這種方式可以將所有工程的通用描述包含進(jìn)來(lái),我們還用來(lái)在此文件中描述了dll文件簽名等其他內(nèi)容。

      八、程序打包發(fā)布

      ? ? 最后一步就是打包發(fā)布了, Framework中發(fā)布將編譯后的站點(diǎn)目錄進(jìn)行打包,但是在Core中需要調(diào)用dotnet命令發(fā)布,發(fā)布之后還要考慮資源文件,dll版本,使用 dotnet publish {啟動(dòng)項(xiàng)目相對(duì)路徑}?命令發(fā)布即可,在平臺(tái)服務(wù)中我們還使用了將獨(dú)立發(fā)布的模式。

      ? ? 因?yàn)镋RP是前后端在一個(gè)倉(cāng)庫(kù),而且有眾多的資源文件,這里給出發(fā)布的腳本僅供大家參考:

      九、總結(jié)

      ? ? 在改造過(guò)程中由于要兼容老的Framework的功能,給整個(gè)過(guò)程帶來(lái)了很多需要兼容的問(wèn)題。初看之下可能會(huì)很亂,但是在一步步分析之后還是有思路可以做,并且在改造過(guò)程中大量采用了條件編譯延伸出來(lái)的技巧,使改造過(guò)程的思路和方法越來(lái)越清晰,最終完成了整個(gè)改造專項(xiàng)。

      ? ? 在整個(gè)過(guò)程中也遇到代碼不兼容的場(chǎng)景,這個(gè)時(shí)候就考慮從功能層面來(lái)兼容,比如:授權(quán)和權(quán)限,頁(yè)面路由,資源文件合并和替換等等,這些具體到功能細(xì)節(jié)改造的部分,將會(huì)在后面文章中陸續(xù)進(jìn)行介紹,敬請(qǐng)期待。

      ------ END ------

      作者簡(jiǎn)介

      熊同學(xué):?研發(fā)工程師,目前負(fù)責(zé)ERP平臺(tái)相關(guān)的設(shè)計(jì)與開發(fā)工作。

      也許您還想看

      .NET Core MVC擴(kuò)展實(shí)踐

      研發(fā)協(xié)同平臺(tái)架構(gòu)演進(jìn)

      明源云助手產(chǎn)品日志服務(wù)的演化歷程

      ERP緩存實(shí)踐經(jīng)驗(yàn)分享

    總結(jié)

    以上是生活随笔為你收集整理的【复杂系统迁移 .NET Core平台系列】之迁移项目工程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。