1. 程式人生 > >.NetCore技術研究-一套程式碼同時支援.NET Framework和.NET Core

.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