使用跨平臺工具開發庫

来源:http://www.cnblogs.com/wtbtbd/archive/2017/11/04/7782889.html
-Advertisement-
Play Games

使用跨平臺工具開發庫 本文介紹如何使用跨平臺 CLI 工具編寫 .NET 的庫。 CLI 提供可跨任何支持的 OS 工作的高效低級別體驗。 仍可使用 Visual Studio 生成庫,如果你首選這種體驗,請 "參閱 Visual Studio 指南" 。 先決條件 需要在電腦上安裝 ".NET ...


使用跨平臺工具開發庫

本文介紹如何使用跨平臺 CLI 工具編寫 .NET 的庫。 CLI 提供可跨任何支持的 OS 工作的高效低級別體驗。 仍可使用 Visual Studio 生成庫,如果你首選這種體驗,請參閱 Visual Studio 指南

先決條件

需要在電腦上安裝 .NET Core SDK 和 CLI

對於本文檔中處理 .NET Framework 版本的部分,需要在 Windows 電腦上安裝 .NET Framework

此外,如果想要支持較舊的 .NET Framework 目標,需要從 .NET 目標平臺頁面安裝用於較舊 Framework 版本的目標包/開發人員工具包。 請參閱此表:

.NET Framework 版本 下載內容
4.6.1 .NET Framework 4.6.1 目標包
4.6 .NET Framework 4.6 目標包
4.5.2 .NET Framework 4.5.2 開發人員工具包
4.5.1 .NET Framework 4.5.1 開發人員工具包
4.5 適用於 Windows 8 的 Windows 軟體開發工具包
4.0 Windows SDK for Windows 7 和 .NET Framework 4
2.0、3.0 和 3.5 .NET Framework 3.5 SP1 運行時(或 Windows 8+ 版本)

如何以 .NET Standard 為目標

如果對 .NET Standard 不是很熟悉,請參閱 瞭解詳細信息。

在該文中,提供有一個將 .NET Standard 版本映射到各種實現的表格:

[!INCLUDE net-standard-table]

以下是此表格對於創建庫的意義:

選擇 .NET Standard 版本時,需要在能夠訪問最新 API 與能夠定位更多 .NET 實現代碼和 .NET Standard 版本之間進行權衡。 通過選擇 netstandardX.X 版本(其中 X.X 是版本號)並將其添加到項目文件(.csproj.fsproj),控制可面向的平臺和版本範圍。

面向 .NET Standard 時,有三種主要選項,具體取決於你的需求。

  1. 可使用 .NET Standard 的預設版本,該版本由 netstandard1.4 模板提供,可提供對 .NET Standard 上大多數 API 的訪問許可權,同時仍與 UWP、.NET Framework 4.6.1 和即將推出的 .NET Standard 2.0 相容。

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFramework>netstandard1.4</TargetFramework>
      </PropertyGroup>
    </Project>
  2. 可通過修改項目文件 TargetFramework 節點中的值來使用更低或更高版本的 .NET Standard。

    .NET Standard 版本可後向相容。 這意味著 netstandard1.0 庫可在 netstandard1.1 平臺以及更高版本上運行。 但是,不可向前相容,即版本較低的 .NET Standard 平臺無法引用版本較高的平臺。 這意味著 netstandard1.0 庫不能引用面向 netstandard1.1 或更高版本的庫。 選擇適合所需、恰當混合有 API 和平臺支持的 Standard 版本。 目前,我們建議 netstandard1.4

  3. 如果希望面向 .NET Framework 版本 4.0 或更低版本,或者要使用 .NET Framework 中提供但 .NET Standard 中不提供的 API(例如 System.Drawing),請閱讀以下部分,瞭解如何設定多目標。

如何以 .NET Framework 為目標

[!NOTE]
這些說明假定電腦上安裝有 .NET Framework。 請參閱先決條件 獲取安裝的依賴項。

請記住,此處使用的某些 .NET Framework 版本不再受支持。 有關不受支持的版本信息,請參閱 .NET Framework 支持生命周期策略常見問題

如果要達到最大數量的開發人員和項目,可將 .NET Framework 4.0 用作基線目標。 若要以 .NET Framework 為目標,首先需要使用與要支持的 .NET Framework 版本相對應的正確目標框架名字對象 (TFM)。

.NET Framework 2.0   --> net20
.NET Framework 3.0   --> net30
.NET Framework 3.5   --> net35
.NET Framework 4.0   --> net40
.NET Framework 4.5   --> net45
.NET Framework 4.5.1 --> net451
.NET Framework 4.5.2 --> net452
.NET Framework 4.6   --> net46
.NET Framework 4.6.1 --> net461
.NET Framework 4.6.2 --> net462
.NET Framework 4.7   --> net47

然後將此 TFM 插入項目文件的 TargetFramework 部分。 例如,以下是如何編寫面向 .NET Framework 4.0 的庫:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net40</TargetFramework>
  </PropertyGroup>
</Project>

就是這麼簡單! 雖然此庫僅針對 .NET Framework 4 編譯,但可在較新版本的 .NET Framework 上使用此庫。

如何設定多目標

[!NOTE]
以下說明假定電腦上安裝有 .NET Framework。 請參閱先決條件部分,瞭解需要安裝哪些依賴項以及在何處下載。

如果項目同時支持 .NET Framework 和 .NET Core,可能需要面向較舊版本的 .NET Framework。 在此方案中,如果要為較新目標使用較新的 API 和語言構造,請在代碼中使用 #if 指令。 可能還需要為要面向的每個平臺添加不同的包和依賴項,以包含每種情況所需的不同 API。

例如,假設有一個庫,它通過 HTTP 執行聯網操作。 對於 .NET Standard 和 .NET Framework 版本 4.5 或更高版本,可從 System.Net.Http 命名空間使用 HttpClient 類。 但是,.NET Framework 的早期版本沒有 HttpClient 類,因此可對早期版本使用 System.Net 命名空間中的 WebClient 類。

項目文件可能如下所示:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netstandard1.4;net40;net45</TargetFrameworks>
  </PropertyGroup>

  <!-- Need to conditionally bring in references for the .NET Framework 4.0 target -->
  <ItemGroup Condition="'$(TargetFramework)' == 'net40'">
    <Reference Include="System.Net" />
  </ItemGroup>

  <!-- Need to conditionally bring in references for the .NET Framework 4.5 target -->
  <ItemGroup Condition="'$(TargetFramework)' == 'net45'">
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Threading.Tasks" />
  </ItemGroup>
</Project>

在此處可看到三項主要更改:

  1. TargetFramework 節點已替換為 TargetFrameworks,其中表示了三個 TFM。
  2. net40 目標有一個 <ItemGroup> 節點,拉取一個 .NET Framework 引用。
  3. net45 目標中有一個 <ItemGroup> 節點,拉取兩個 .NET Framework 引用。

生成系統可識別以下用在 #if 指令中的處理器符號:

[!INCLUDE Preprocessor symbols]

以下是使用每目標條件編譯的示例:

using System;
using System.Text.RegularExpressions;
#if NET40
// This only compiles for the .NET Framework 4 targets
using System.Net;
#else
 // This compiles for all other targets
using System.Net.Http;
using System.Threading.Tasks;
#endif

namespace MultitargetLib
{
    public class Library
    {
#if NET40
        private readonly WebClient _client = new WebClient();
        private readonly object _locker = new object();
#else
        private readonly HttpClient _client = new HttpClient();
#endif

#if NET40
        // .NET Framework 4.0 does not have async/await
        public string GetDotNetCount()
        {
            string url = "http://www.dotnetfoundation.org/";

            var uri = new Uri(url);

            string result = "";

            // Lock here to provide thread-safety.
            lock(_locker)
            {
                result = _client.DownloadString(uri);
            }

            int dotNetCount = Regex.Matches(result, ".NET").Count;

            return $"Dotnet Foundation mentions .NET {dotNetCount} times!";
        }
#else
        // .NET 4.5+ can use async/await!
        public async Task<string> GetDotNetCountAsync()
        {
            string url = "http://www.dotnetfoundation.org/";

            // HttpClient is thread-safe, so no need to explicitly lock here
            var result = await _client.GetStringAsync(url);

            int dotNetCount = Regex.Matches(result, ".NET").Count;

            return $"dotnetfoundation.org mentions .NET {dotNetCount} times in its HTML!";
        }
#endif
    }
}

如果使用 dotnet build 生成此項目,則在 bin/ 文件夾下有三個目錄:

net40/
net45/
netstandard1.4/

其中每個目錄都包含每個目標的 .dll 文件。

如何在 .NET Core 上測試庫

能夠跨平臺進行測試至關重要。 可使用現成的 xUnit 或 MSTest。 它們都十分適合在 .NET Core 上對庫進行單元測試。 如何使用測試項目設置解決方案取決於解決方案的結構。 下麵的示例假設測試和源目錄位於同一頂級目錄下。

[!NOTE]
此示例將使用某些 .NET Core CLI 命令。 有關詳細信息,請參閱 dotnet newdotnet sln

  1. 設置解決方案。 可使用以下命令實現此目的:

bash mkdir SolutionWithSrcAndTest cd SolutionWithSrcAndTest dotnet new sln dotnet new classlib -o MyProject dotnet new xunit -o MyProject.Test dotnet sln add MyProject/MyProject.csproj dotnet sln add MyProject.Test/MyProject.Test.csproj

這將創建多個項目,並一個解決方案中將這些項目鏈接在一起。 SolutionWithSrcAndTest 的目錄應如下所示:

/SolutionWithSrcAndTest |__SolutionWithSrcAndTest.sln |__MyProject/ |__MyProject.Test/

  1. 導航到測試項目的目錄,然後添加對 MyProject 中的 MyProject.Test 的引用。

bash cd MyProject.Test dotnet add reference ../MyProject/MyProject.csproj

  1. 還原包和生成項目:

bash dotnet restore dotnet build

  1. 執行 dotnet test 命令,驗證 xUnit 是否在運行。 如果選擇使用 MSTest,則應改為運行 MSTest 控制台運行程式。

就是這麼簡單! 現在可以使用命令行工具跨所有平臺測試庫。 若要繼續測試,現已設置好了所有內容,測試庫將非常簡單:

  1. 對庫進行更改。
  2. 使用 dotnet test 命令在測試目錄中從命令行運行測試。

調用 dotnet test 命令時,將自動重新生成代碼。

如何使用多個項目

對於較大的庫,通常需要將功能置於不同項目中。

假設要生成一個可以慣用的 C# 和 F# 使用的庫。 這意味著庫的使用者可通過對 C# 或 F# 來說很自然的方式來使用它們。 例如,在 C# 中,了能會這樣使用庫:

using AwesomeLibrary.CSharp;

public Task DoThings(Data data)
{
    var convertResult = await AwesomeLibrary.ConvertAsync(data);
    var result = AwesomeLibrary.Process(convertResult);
    // do something with result
}

在 F# 中可能是這樣:

open AwesomeLibrary.FSharp

let doWork data = async {
    let! result = AwesomeLibrary.AsyncConvert data // Uses an F# async function rather than C# async method
    // do something with result
}

這樣的使用方案意味著被訪問的 API 必須具有用於 C# 和 F# 的不同結構。 通常的方法是將庫的所有邏輯因數轉化到核心項目中,C# 和 F# 項目定義調用到核心項目的 API 層。 該部分的其餘部分將使用以下名稱:

  • AwesomeLibrary.Core - 核心項目,其中包含庫的所有邏輯
  • AwesomeLibrary.CSharp - 具有打算在 C# 中使用的公共 API 的項目
  • AwesomeLibrary.FSharp - 具有打算在 F# 中使用的公共 API 的項目

可在終端運行下列命令,生成與下列指南相同的結構:

mkdir AwesomeLibrary && cd AwesomeLibrary
dotnet new sln
mkdir AwesomeLibrary.Core && cd AwesomeLibrary.Core && dotnet new classlib
cd ..
mkdir AwesomeLibrary.CSharp && cd AwesomeLibrary.CSharp && dotnet new classlib
cd ..
mkdir AwesomeLibrary.FSharp && cd AwesomeLibrary.FSharp && dotnet new classlib -lang F#
cd ..
dotnet sln add AwesomeLibrary.Core/AwesomeLibrary.Core.csproj
dotnet sln add AwesomeLibrary.CSharp/AwesomeLibrary.CSharp.csproj
dotnet sln add AwesomeLibrary.FSharp/AwesomeLibrary.FSharp.fsproj

這將添加上述三個項目和將它們鏈接在一起的解決方案文件。 創建解決方案文件並鏈接項目後,可從頂級還原和生成項目。

項目到項目的引用

引用項目的最佳方式是使用 .NET Core CLI 添加項目引用。 在 AwesomeLibrary.CSharp 和 AwesomeLibrary.FSharp 項目目錄中,可運行下列命令:

$ dotnet add reference ../AwesomeLibrary.Core/AwesomeLibrary.Core.csproj

AwesomeLibrary.CSharp 和 AwesomeLibrary.FSharp 的項目文件現在需要將 AwesomeLibrary.Core 作為 ProjectReference 目標引用。 可通過檢查項目文件和查看其中的下列內容來進行驗證:

<ItemGroup>
  <ProjectReference Include="..\AwesomeLibrary.Core\AwesomeLibrary.Core.csproj" />
</ItemGroup>

如果不想使用 .NET Core CLI,可手動將此部分添加到每個項目文件。

結構化解決方案

多項目解決方案的另一個重要方面是建立良好的整體項目結構。 可根據自己的喜好隨意組織代碼,只要使用 dotnet sln add 將每個項目鏈接到解決方案文件,就可在解決方案級別運行 dotnet restoredotnet build


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • http://www.cnblogs.com/chenqf/p/6386163.html ...
  • Barrier類用於組織多個線程及時在某個時刻會面,其提供一個回調函數,每次線程調用了SignalAndWait方法後該回調函數就會被執行。 ...
  • InstancePerLifetimeScope:同一個Lifetime生成的對象是同一個實例 SingleInstance:單例模式,每次調用,都會使用同一個實例化的對象;每次都用同一個對象; InstancePerDependency:預設模式,每次調用,都會重新實例化對象;每次請求都創建一個新 ...
  • localStorage和sessionStorage一樣都是用來存儲客戶端臨時信息的對象。localStorage生命周期是永久sessionStorage生命周期為當前視窗或標簽頁,一旦視窗或標簽頁被永久關閉了,那麼所有通過sessionStorage存儲的數據也就被清空了 ...
  • Lua是一種很好的擴展性語言,Lua解釋器被設計成一個很容易嵌入到宿主程式的庫。LuaInterface則用於實現Lua和CLR的混合編程。 (一)C#調用Lua 測試環境:在VS2015中建一個C#控制台應用程式,並添加LuaInterface.dll的引用 LuaInterface下載地址:ht ...
  • 主機:Linux x641.Android模擬器,模擬器設置 >打開Enable Usb Debug2.在主機上安裝firefox,最低v36.菜單 >開發者 >WebIDE 地址欄輸入about:config,新建以下兩個值[email protected] ...
  • 在mac os系統上反編譯android apk,首先需要準備好以下3個文件: 1、apktool:https://ibotpeaches.github.io/Apktool/install/ 2、dex2jar:https://github.com/pxb1988/dex2jar 3、jd-gui ...
  • 1.View方法 ActionResult解析:(抽象類)視圖結果 子類: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...