使用跨平臺工具開發庫

来源: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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...