.NetCore技術研究-一套程式碼同時支援.NET Framework和.NET Core
在.NET Core的遷移過程中,我們將原有的.NET Framework程式碼遷移到.NET Core。如果線上只有一個小型的應用還好,遷移升級完成後,只需要維護.NET Core這個版本的程式碼。
但是,如果是一個大型分散式應用,幾百臺Server,上千個.NET 應用程序。這種場景下,在一定的時期內,我們需要同時維護.NET Framework和.NET Core兩套程式碼,同一個產品
特性,需要分別在兩套程式碼中實現,這種程式碼同步的工作量是非常大的。因此,在這種場景下,有必要使用同一套程式碼既支援.NET Framework又支援.NET Core.
帶著這個需求場景,我們展開今天的.NET Core技術研究分享。先總結一下整體的思路:
1. 在Project工程層面支援多個目標框架,面向不同的.NET 目標框架新增不同的引用
2. 程式碼中使用預處理指令同時支援.NET Framework 和 .NET Core
3. 編譯生成兩個.NET框架的Dll,製作支援多個.NET目標框架的Nuget包
我們先看第一步:
一、在Project工程層面支援多個目標框架,面向不同的.NET 目標框架新增不同的引用
在這個示例程式碼中,我們使用了.NET Standard 2.0 Class Library Project。 目標框架同時支援.NET Framework 4.5.1和.NET Standard 2.0
雙擊Project, 進入XML檔案編輯模式
1 <Project Sdk="Microsoft.NET.Sdk"> 2 <PropertyGroup> 3 <TargetFramework>netstandard2.0</TargetFramework> 4 </PropertyGroup> 5 </Project>
我們重點編輯TargetFramework這個節,改為TargetFrameworks,例如:
1 <PropertyGroup> 2 <TargetFrameworks>netstandard2.0;net451</TargetFrameworks> 3 </PropertyGroup>
儲存後,會提示:
全部重新載入後,新的Project的依賴項是這樣的:
這樣,這個Project就支援了多個.NET 目標框架,我們可以面向不同的.NET 目標框架新增不同的引用,當然如果依賴的Nuget也同時支援相同的.NET 目標框架,那就最匹配了:例如:Newtonsoft.Json
新增Nuget引用後,Project在不同的.NET 目標框架的引用是這樣的:
當然,我們可以為單獨為指定的.NET 目標框架新增不同的引用,例如:
1 <Project Sdk="Microsoft.NET.Sdk"> 2 3 <PropertyGroup> 4 <TargetFrameworks>netstandard2.0;net451;</TargetFrameworks> 5 </PropertyGroup> 6 7 <ItemGroup> 8 <PackageReference Include="Newtonsoft.Json" Version="12.0.2" /> 9 </ItemGroup> 10 11 <ItemGroup Condition=" '$(TargetFramework)' == 'net451' "> 12 <ProjectReference Include="..\LibNetFramework\LibNetFramework.csproj" /> 13 </ItemGroup> 14 15 <ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' "> 16 <ProjectReference Include="..\LibNetCore\LibNetCore.csproj" /> 18 </ItemGroup> 19 20 </Project>
參考連結:https://docs.microsoft.com/en-us/dotnet/standard/frameworks
二、. 程式碼中使用預處理指令同時支援.NET Framework 和 .NET Core
如果同一塊業務邏輯,在.NET Framework和.NET Core實現不一樣,我們在同一個程式碼中,如果通過預處理指令實現:
1 public string UserID 2 { 3 get 4 { 5 #if NET451 6 return Convert.ToString(HttpContext.Current.Session["UserID"]); 7 #elif NETSTANDARD2_0 8 return httpContext.Session.GetString("UserID"); 9 #endif 10 } 11 private set 12 { 13 #if NET451 14 HttpContext.Current.Session["UserID"] = value; 15 #elif NETSTANDARD2_0 16 httpContext.Session.SetString("UserID", value); 17 #endif 18 } 19 }
參考連結:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-if
這個地方有個對照表:
這樣,程式碼寫完後,編譯一下,可以看到有兩個資料夾生成:
1>------ 已啟動全部重新生成: 專案: LibNetCore, 配置: Debug Any CPU ------ 1>C:\Program Files\dotnet\sdk\3.0.100-preview3-010431\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.RuntimeIdentifierInference.targets(151,5): message NETSDK1057: 你正在使用 .NET Core 的預覽版。請檢視 https://aka.ms/dotnet-core-preview 1>LibNetCore -> C:\Users\zhougq\source\repos\LibNetCore\bin\Debug\netstandard2.0\LibNetCore.dll 2>------ 已啟動全部重新生成: 專案: TestLibrary, 配置: Debug Any CPU ------ 2>C:\Program Files\dotnet\sdk\3.0.100-preview3-010431\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.RuntimeIdentifierInference.targets(151,5): message NETSDK1057: 你正在使用 .NET Core 的預覽版。請檢視 https://aka.ms/dotnet-core-preview 2>TestLibrary -> C:\Users\zhougq\source\repos\TestLibrary\bin\Debug\netstandard2.0\TestLibrary.dll 2>TestLibrary -> C:\Users\zhougq\source\repos\TestLibrary\bin\Debug\net451\TestLibrary.dll ========== 全部重新生成: 成功 2 個,失敗 0 個,跳過 0 個 ==========
三. 編譯生成兩個.NET框架的Dll,製作支援多個.NET目標框架的Nuget包
上個步驟中生成的兩個.NET 目標版本的dll,可以分別製作支援多個.NET 目標框架的Nuget包。
右鍵Project屬性設定中,可以設定Nuget打包
編譯工程:Successfully created package 'C:\Users\zhougq\source\repos\TestLibrary\bin\Debug\TestLibrary.1.0.0.nupkg'.
使用PackageExplorer編輯生成好的Nuget包:
以上就是本次的.NETCore 技術分享。
周國慶
2019/9/30