当前位置: 首页 > news >正文

解锁.NET Standard库:从0到1的创建与打包秘籍

一、引言

在当今的软件开发领域,跨平台开发已成为一种趋势。随着不同操作系统和设备的多样化,开发人员需要确保他们的代码能够在多个平台上运行,以满足更广泛的用户需求。.NET Standard 库应运而生,它定义了一组公共 API,允许开发人员编写可在多个.NET 实现中共享的代码,包括.NET Framework、.NET Core 和 Xamarin 等。

以一个实际应用场景为例,假设你正在开发一个企业级的数据分析应用程序。这个应用程序需要在 Windows 服务器上进行数据处理,同时也需要在 Linux 服务器上进行部署以实现分布式计算。此外,为了方便用户随时随地查看数据,还需要开发一个移动端应用,支持 iOS 和 Android 系统。在这种情况下,使用.NET Standard 库可以大大简化开发过程。你可以将核心的数据处理逻辑封装在一个.NET Standard 库中,然后在不同平台的项目中引用这个库,避免了重复编写相同的代码。这样不仅提高了开发效率,还降低了维护成本。

正是由于.NET Standard 库在跨平台开发中具有如此重要的作用,掌握如何创建和打包它成为了.NET 开发人员必备的技能。接下来,本文将详细介绍创建和打包.NET Standard 库的步骤和方法,帮助你快速上手,开启跨平台开发之旅。

二、前期准备

2.1 开发环境搭建

要创建和打包.NET Standard 库,首先需要搭建合适的开发环境。这包括安装开发工具和配置相关的软件开发工具包(SDK)。

  • 安装 Visual Studio

    • 下载:Visual Studio 是微软官方提供的一款功能强大的集成开发环境(IDE),支持多种编程语言和项目类型。你可以从Visual Studio 官方下载页面获取安装程序。在下载页面中,根据你的操作系统(如 Windows)和需求选择合适的版本,如社区版(免费且适用于个人开发者和小型团队)、专业版或企业版。
    • 安装:运行下载的安装程序,在安装向导中,你可以选择所需的工作负载。对于创建.NET Standard 库,建议选择 “.NET 桌面开发” 工作负载,它包含了开发.NET 项目所需的基本工具和组件。同时,你还可以根据个人喜好选择安装位置和其他相关选项。安装过程中,系统可能会提示你安装一些依赖组件,按照提示进行操作即可。安装完成后,启动 Visual Studio。
  • 安装 Visual Studio Code

    • 下载:Visual Studio Code 是一款轻量级的跨平台代码编辑器,具有丰富的插件生态系统,也非常适合用于.NET 开发。你可以从Visual Studio Code 官方网站下载对应操作系统的安装包。
    • 安装:运行安装包,按照安装向导的提示完成安装。安装完成后,打开 Visual Studio Code,为了能够进行.NET 开发,需要安装 C# 插件。在 Visual Studio Code 的扩展面板中,搜索 “C#”,找到由 Microsoft 发布的 “C#” 插件并进行安装。安装完成后,重启 Visual Studio Code 使插件生效。
  • 配置.NET SDK

    • 下载:.NET SDK 是开发.NET 应用程序的核心工具,它包含了编译器、运行时和各种库。你可以从.NET 官方下载页面获取最新版本的.NET SDK。在下载页面,根据你的操作系统选择对应的下载链接,如 Windows x64 Installer、macOS Installer 或 Linux Installer。
    • 安装:运行下载的安装程序,按照安装向导的提示完成安装。安装完成后,打开命令提示符(Windows)或终端(macOS、Linux),输入dotnet --version命令,如果显示出安装的.NET SDK 版本号,则说明安装成功。例如,输出 “8.0.100” 表示你安装的是.NET 8.0 版本的 SDK。此外,还可以通过dotnet --list-sdks命令查看系统中已安装的所有.NET SDK 版本。

2.2 了解相关概念

在开始创建和打包.NET Standard 库之前,有必要了解一些相关的概念,这将有助于你更好地理解整个过程和做出正确的决策。

  • .NET Standard 库的概念:.NET Standard 是一个正式定义的 API 规范集,它不是一个实际的运行时或框架,而是定义了一组所有.NET 实现(如.NET Framework、.NET Core、Xamarin 等)都应实现的标准 API。.NET Standard 库就是遵循这些标准 API 编写的类库,这使得它具有高度的跨平台性和跨框架兼容性。

  • .NET Standard 库的作用:它允许开发人员编写一次代码,然后在多个不同的.NET 平台上使用,而无需为每个平台单独编写代码。这大大提高了代码的复用性和可维护性,减少了开发成本和工作量。例如,你可以创建一个包含通用数据处理逻辑的.NET Standard 库,然后在基于.NET Framework 的 Windows 桌面应用、基于.NET Core 的 Web 应用以及基于 Xamarin 的移动应用中都能使用这个库。

  • 与其他.NET 平台的关系:.NET Framework 是微软早期开发的针对 Windows 平台的框架,它包含了丰富的类库和功能,但主要用于 Windows 操作系统。.NET Core 是一个跨平台的、开源的框架,旨在提供高性能和轻量级的开发体验,适用于云、微服务和跨平台应用开发。Xamarin 则专注于移动应用开发,允许使用 C# 编写 iOS 和 Android 应用。.NET Standard 作为一个统一的 API 规范,被这些不同的.NET 平台所实现。也就是说,.NET Framework、.NET Core 和 Xamarin 等都实现了.NET Standard 定义的 API,从而使得.NET Standard 库能够在这些平台上运行 。

  • 为何要创建和打包.NET Standard 库:创建.NET Standard 库可以将通用的代码逻辑封装起来,便于在不同的项目和平台中复用。而打包成 NuGet 包则是一种方便的代码分发方式。通过将.NET Standard 库打包成 NuGet 包,其他开发人员可以轻松地在他们的项目中引用和使用这个库,只需要通过 NuGet 包管理器进行安装即可,无需手动复制代码文件。这不仅提高了代码的共享效率,还方便了库的版本管理和更新。例如,你开发了一个优秀的数学计算库,将其创建为.NET Standard 库并打包成 NuGet 包后,其他开发者可以在他们的项目中快速集成这个库,而你也可以通过更新 NuGet 包的版本来提供新功能或修复问题。

三、创建.NET Standard 库项目

3.1 使用 Visual Studio 创建

使用 Visual Studio 创建.NET Standard 库项目是一种直观且便捷的方式,尤其适合初学者。下面将详细介绍具体步骤:

  1. 启动 Visual Studio:在开始菜单中找到并点击 Visual Studio 图标,等待其启动完成。

  2. 新建项目:在 Visual Studio 的起始页面中,点击 “创建新项目” 选项。如果已经打开了一个项目,可以通过菜单栏中的 “文件” -> “新建” -> “项目” 来创建新项目。

  3. 选择模板:在 “创建新项目” 窗口中,在搜索框中输入 “类库 (.NET Standard)”。此时,Visual Studio 会筛选出相关的模板,选择 “类库 (.NET Standard)” 模板,然后点击 “下一步” 按钮。

  4. 命名项目:在 “配置新项目” 页面,为项目输入一个有意义的名称,例如 “MathLibrary”。同时,你还可以选择项目的保存位置和解决方案名称。解决方案是一个或多个项目的容器,它可以帮助你更好地组织和管理项目。完成这些设置后,点击 “创建” 按钮

  5. 等待项目创建完成:Visual Studio 会根据你选择的模板和设置创建项目。这个过程可能需要一些时间,取决于你的计算机性能和网络状况。创建完成后,你将看到项目的解决方案资源管理器,其中包含项目文件和默认的 Class1.cs 文件,

3.2 使用 dotnet CLI 创建

对于喜欢使用命令行的开发人员,使用 dotnet CLI(命令行界面)创建.NET Standard 库项目更加高效和灵活。它不受 IDE 界面的限制,可以在各种终端环境中使用,并且适合自动化脚本和持续集成 / 持续部署(CI/CD)流程。以下是使用 dotnet CLI 创建项目的详细步骤:

  1. 打开命令提示符或终端:在 Windows 系统中,可以通过开始菜单搜索 “命令提示符” 来打开;在 macOS 和 Linux 系统中,可以通过应用程序列表或快捷键打开终端。

  2. 切换到目标目录:使用cd命令切换到你希望创建项目的目录。例如,如果要在 D 盘的 Projects 文件夹下创建项目,可以输入cd D:\Projects。

  3. 执行创建项目命令:在命令行中输入以下命令来创建.NET Standard 库项目:

dotnet new classlib -n MathLibrary -f netstandard2.1

在这个命令中:

  • dotnet new是创建新项目的基本命令。

  • classlib表示要创建的项目类型是类库。

  • -n参数用于指定项目名称,这里是 “MathLibrary”。

  • -f参数用于指定目标框架,“netstandard2.1” 是一个常用的.NET Standard 版本,它提供了广泛的平台兼容性和功能支持。你可以根据项目需求选择不同的.NET Standard 版本,例如 “netstandard2.0” 等 。

  1. 等待项目创建完成:命令执行后,dotnet CLI 会在指定目录下创建项目文件和文件夹结构。创建完成后,你可以在目标目录中看到生成的项目文件,其中包括项目文件(.csproj)和默认的类文件(Class1.cs)。

  2. 验证项目:为了确保项目创建成功,可以进入项目目录,然后执行dotnet build命令来编译项目。如果编译过程中没有错误,说明项目创建成功。例如:

cd MathLibrary
dotnet build

执行上述命令后,如果看到类似 “Build succeeded.” 的提示信息,就表示项目已经成功创建并编译通过。

四、编写库代码

4.1 项目结构介绍

当你创建一个.NET Standard 库项目后,会得到一个默认的项目结构。以使用 Visual Studio 创建的 “MathLibrary” 项目为例,在解决方案资源管理器中,你会看到以下主要内容:

  • 项目文件(.csproj):这是项目的核心文件,它包含了项目的配置信息,如项目名称、目标框架、引用的依赖项等。例如,在 “MathLibrary.csproj” 文件中,你可以看到标签,它指定了项目使用的 SDK。标签中包含了netstandard2.1,这表明项目的目标框架是.NET Standard 2.1。此外,还可以在这个文件中添加或管理项目的依赖项,如表示引用了 Newtonsoft.Json 库,版本为 13.0.1。

  • Class1.cs:这是默认生成的代码文件,它是一个空的类文件,位于项目的根目录下。在这个文件中,你可以开始编写库的代码逻辑。例如,默认的代码结构如下:

namespace MathLibrary
{public class Class1{}
}

其中,namespace MathLibrary定义了命名空间,它用于组织代码,避免命名冲突。在实际开发中,建议将Class1.cs重命名为更具描述性的名称,比如 “MathOperations.cs”,这样可以更清晰地表达该文件中代码的功能。

随着项目的发展,代码量会逐渐增加,合理组织代码文件和目录结构变得至关重要。一种常见的做法是根据功能模块来划分目录。例如,对于一个包含多种数学运算的库,可以创建一个 “Operations” 目录,将不同运算相关的代码文件放在这个目录下。比如,创建 “Addition.cs” 文件用于实现加法运算,“Multiplication.cs” 文件用于实现乘法运算等。这样的目录结构可以使项目的代码层次更加清晰,易于维护和扩展。在项目根目录下,还可以创建 “Interfaces” 目录用于存放接口定义,“Enums” 目录用于存放枚举类型定义等。通过这种方式,将相关的代码逻辑组织在一起,提高代码的可读性和可维护性。

4.2 示例代码编写

为了更好地展示如何编写.NET Standard 库的代码,我们以一个简单的数学计算库为例。假设我们要在这个库中实现基本的加、减、乘、除运算。

  1. 添加类:在项目中添加一个新的类文件,将其命名为 “MathCalculator.cs”。在 Visual Studio 中,可以右键点击项目,选择 “添加” -> “类”,然后输入类名 “MathCalculator.cs” 并点击 “添加” 按钮。

  2. 编写方法:在 “MathCalculator.cs” 文件中,编写实现加、减、乘、除运算的方法,具体代码如下:

using System;namespace MathLibrary
{/// <summary>/// 数学计算类,提供基本的数学运算方法/// </summary>public class MathCalculator{/// <summary>/// 加法运算,将两个整数相加/// </summary>/// <param name="a">第一个整数</param>/// <param name="b">第二个整数</param>/// <returns>两个整数相加的结果</returns>public static int Add(int a, int b){return a + b;}/// <summary>/// 减法运算,用第一个整数减去第二个整数/// </summary>/// <param name="a">被减数</param>/// <param name="b">减数</param>/// <returns>减法运算的结果</returns>public static int Subtract(int a, int b){return a - b;}/// <summary>/// 乘法运算,将两个整数相乘/// </summary>/// <param name="a">第一个整数</param>/// <param name="b">第二个整数</param>/// <returns>两个整数相乘的结果</returns>public static int Multiply(int a, int b){return a * b;}/// <summary>/// 除法运算,用第一个整数除以第二个整数/// </summary>/// <param name="a">被除数</param>/// <param name="b">除数,不能为0</param>/// <returns>除法运算的结果</returns>/// <exception cref="DivideByZeroException">当除数为0时抛出此异常</exception>public static double Divide(int a, int b){if (b == 0){throw new DivideByZeroException("除数不能为0");}return (double)a / b;}}
}

在上述代码中:

  • 首先定义了MathCalculator类,它位于MathLibrary命名空间下。

  • Add方法实现了加法运算,接受两个整数参数a和b,返回它们的和。

  • Subtract方法实现了减法运算,接受两个整数参数a和b,返回a减去b的结果。

  • Multiply方法实现了乘法运算,接受两个整数参数a和b,返回它们的乘积。

  • Divide方法实现了除法运算,接受两个整数参数a和b。在方法内部,首先检查除数b是否为 0,如果为 0,则抛出DivideByZeroException异常,提示除数不能为 0;否则,将a转换为双精度浮点数后除以b,返回除法运算的结果 。

  • 每个方法都添加了详细的 XML 注释,用于描述方法的功能、参数和返回值等信息。这些注释不仅有助于代码的可读性,还可以在其他项目引用该库时,通过智能提示展示方法的相关说明,方便开发者使用。

五、测试你的库

5.1 添加单元测试项目

在完成.NET Standard 库的代码编写后,为了确保库的功能正确性和稳定性,需要对其进行测试。添加单元测试项目是一种有效的测试方式,它可以对库中的各个方法进行单独测试,验证其是否符合预期。以使用 Visual Studio 为例,以下是添加单元测试项目的详细步骤:

  1. 右键解决方案:在 Visual Studio 的解决方案资源管理器中,找到包含.NET Standard 库项目的解决方案,右键点击该解决方案,在弹出的菜单中选择 “添加” -> “新建项目”

  2. 选择单元测试项目模板:在 “添加新项目” 窗口中,在搜索框中输入 “单元测试项目 (.NET Core)”,然后选择该模板,点击 “下一步” 按钮,

  3. 命名单元测试项目:在 “配置新项目” 页面,为单元测试项目输入一个合适的名称,例如 “MathLibrary.Tests”。这样的命名方式可以清晰地表明该项目是用于测试 “MathLibrary” 库的。同时,你还可以选择项目的保存位置和解决方案名称。完成设置后,点击 “创建” 按钮,

  4. 添加对库项目的引用:单元测试项目需要引用被测试的.NET Standard 库项目,以便访问其中的代码。在解决方案资源管理器中,右键点击单元测试项目 “MathLibrary.Tests”,选择 “添加” -> “项目引用”,在弹出的 “引用管理器” 窗口中,勾选 “MathLibrary” 项目,然后点击 “确定” 按钮

  5. 安装测试框架:常用的测试框架有 Xunit、NUnit 等。这里以 Xunit 为例,在解决方案资源管理器中,右键点击单元测试项目 “MathLibrary.Tests”,选择 “管理 NuGet 程序包”,在 “NuGet 程序包管理器” 窗口中,搜索 “xunit”,然后选择 “xunit” 包进行安装。同时,还需要安装 “xunit.runner.visualstudio” 包,它是 Xunit 在 Visual Studio 中的测试运行器,用于执行测试用例并显示测试结果。安装完成后,在项目的依赖项中可以看到这两个包

5.2 编写测试代码

安装好测试框架并添加对库项目的引用后,就可以开始编写测试代码了。测试代码的目的是验证.NET Standard 库中各个方法的功能是否正确。以之前创建的 “MathLibrary” 库为例,我们要测试其中 “MathCalculator” 类的加、减、乘、除方法。以下是使用 Xunit 框架编写的测试代码示例:

using Xunit;
using MathLibrary;namespace MathLibrary.Tests
{public class MathCalculatorTests{[Fact]public void AddTest(){// Arrangeint a = 3;int b = 4;// Actint result = MathCalculator.Add(a, b);// AssertAssert.Equal(7, result);}[Fact]public void SubtractTest(){// Arrangeint a = 7;int b = 3;// Actint result = MathCalculator.Subtract(a, b);// AssertAssert.Equal(4, result);}[Fact]public void MultiplyTest(){// Arrangeint a = 5;int b = 6;// Actint result = MathCalculator.Multiply(a, b);// AssertAssert.Equal(30, result);}[Fact]public void DivideTest(){// Arrangeint a = 10;int b = 2;// Actdouble result = MathCalculator.Divide(a, b);// AssertAssert.Equal(5.0, result);}[Fact]public void DivideByZeroTest(){// Arrangeint a = 10;int b = 0;// Act & AssertAssert.Throws<DivideByZeroException>(() => MathCalculator.Divide(a, b));}}
}

在上述代码中:

  • 每个测试方法都使用了[Fact]特性进行标记,这是 Xunit 框架中用于标识测试方法的特性。

  • 每个测试方法都遵循 “Arrange - Act - Assert” 模式:

    • Arrange:在这一步中,初始化测试所需的变量和对象。例如,在AddTest方法中,定义了两个整数变量a和b,并分别赋值为 3 和 4。
    • Act:执行要测试的方法。在AddTest方法中,调用MathCalculator.Add(a, b)方法,将返回的结果存储在result变量中。
    • Assert:验证方法的执行结果是否符合预期。在AddTest方法中,使用Assert.Equal(7, result)来断言result的值是否等于 7,如果相等,则测试通过;否则,测试失败。
  • 在DivideByZeroTest方法中,使用Assert.Throws(() => MathCalculator.Divide(a, b))来验证当除数为 0 时,MathCalculator.Divide方法是否会抛出DivideByZeroException异常。如果抛出了该异常,则测试通过;否则,测试失败。通过这种方式,可以全面地测试库中方法的各种情况,确保其功能的正确性和稳定性。

六、打包.NET Standard 库

6.1 安装 NuGet 打包工具

NuGet 是.NET 生态系统中用于包管理的重要工具,它允许开发人员轻松地共享和使用代码库。要将.NET Standard 库打包成可供分发的 NuGet 包,首先需要安装 NuGet 打包工具。在 Visual Studio 中安装 NuGet 打包扩展的步骤如下:

  1. 打开扩展和更新窗口:启动 Visual Studio,点击菜单栏中的 “工具” -> “扩展和更新” 选项这将打开 “扩展和更新” 窗口,该窗口用于管理 Visual Studio 的各种扩展。

  2. 搜索并安装:在 “扩展和更新” 窗口的左侧,选择 “联机” 选项。然后,在搜索框中输入 “NuGet 打包扩展”,在搜索结果中,找到 “NuGet Package Manager” 扩展,点击 “下载” 按钮进行安装。安装过程中,Visual Studio 可能会提示你重启,按照提示进行操作即可完成安装。

6.2 配置 NuSpec 文件

安装好 NuGet 打包工具后,接下来需要配置 NuSpec 文件。NuSpec 文件是一个 XML 格式的清单文件,它用于描述 NuGet 包的内容和相关元数据,在打包过程中起着关键作用。以下是在项目根目录创建.nuspec 文件的方法及文件中各字段含义及填写示例:

  1. 创建.nuspec 文件:在项目的解决方案资源管理器中,右键点击项目名称,选择 “添加” -> “新建项”。在 “添加新项” 窗口中,选择 “XML 文件”,并将文件命名为 “MathLibrary.nuspec”(这里的文件名应与项目名称相关,方便识别),然后点击 “添加” 按钮

  2. 各字段含义及填写示例:打开创建好的 “MathLibrary.nuspec” 文件,填写以下内容:

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd"><metadata><!-- 包的唯一标识符,通常与项目名称一致 --><id>MathLibrary</id><!-- 包的版本号,遵循语义化版本控制规范,格式为Major.Minor.Patch[-Suffix] --><version>1.0.0</version><!-- 包的标题,用于在NuGet库中显示 --><title>Math Library</title><!-- 包的作者,可以是个人或团队名称 --><authors>Your Name</authors><!-- 包的所有者,通常与作者相同 --><owners>Your Name</owners><!-- 项目的许可协议链接,例如MIT许可证的链接 --><licenseUrl>https://opensource.org/licenses/MIT</licenseUrl><!-- 项目的主页链接,例如项目的GitHub仓库地址 --><projectUrl>https://github.com/yourusername/MathLibrary</projectUrl><!-- 是否要求用户在安装包时接受许可协议,false表示不要求 --><requireLicenseAcceptance>false</requireLicenseAcceptance><!-- 包的详细描述信息,用于向用户介绍包的功能和用途 --><description>A.NET Standard library for basic math operations</description><!-- 发布说明,记录包的版本更新内容和重要变更 --><releaseNotes>Initial release</releaseNotes><!-- 版权信息,注明包的版权所有者和年份 --><copyright>Copyright 2024</copyright><!-- 标签,用于在NuGet库中搜索和分类包,可以添加多个标签,用空格分隔 --><tags>Math.NET Standard</tags></metadata>
</package>

在上述示例中:

  • 字段设置为 “MathLibrary”,与项目名称一致,确保在 NuGet 库中的唯一性。

  • 字段设置为 “1.0.0”,表示这是包的第一个版本,主版本号为 1,次版本号为 0,修订版本号为 0。如果后续有功能添加或修改,可相应更新版本号,如 “1.1.0” 表示增加了新功能,“1.0.1” 表示修复了一些小问题。

  • 字段设置为 “Math Library”,在 NuGet 库中展示给用户,应简洁明了地描述包的用途。
  • 和字段都设置为 “Your Name”,表明包的作者和所有者。

  • 字段指向 MIT 许可证的链接,说明包的开源许可协议,用户可以根据许可证的规定使用和分发包。

  • 字段设置为项目的 GitHub 仓库地址,方便用户查看项目的源代码和相关文档。

  • 字段设置为 “false”,表示用户在安装包时不需要手动接受许可协议。

  • 字段详细描述了包的功能,即这是一个用于基本数学运算的.NET Standard 库,帮助用户快速了解包的用途。

  • 字段记录了当前版本是初始发布版本,当有新的版本发布时,可在此更新发布说明,如 “Fixed some bugs and added new features”。

  • 字段注明版权所有者为 “Copyright 2024”,表示 2024 年的版权归属。

  • 字段添加了 “Math” 和 “.NET Standard” 标签,方便用户在 NuGet 库中通过这些标签搜索到该包 。

6.3 执行打包操作

完成 NuGet 打包工具的安装和 NuSpec 文件的配置后,就可以执行打包操作,将.NET Standard 库打包成 NuGet 包。以下是在命令行中执行打包命令的过程,以及打包成功后的文件位置和用途:

  1. 打开命令行:在 Windows 系统中,按下 “Win + R” 键,打开 “运行” 对话框,输入 “cmd” 并回车,打开命令提示符。在 macOS 或 Linux 系统中,打开终端应用。

  2. 切换到项目目录:使用cd命令切换到包含.nuspec文件的项目目录。例如,如果项目位于 “D:\Projects\MathLibrary” 目录下,则在命令行中输入cd D:\Projects\MathLibrary。

  3. 执行打包命令:在命令行中输入以下命令进行打包:

nuget pack MathLibrary.nuspec

这里的 “MathLibrary.nuspec” 是之前创建的 NuSpec 文件的名称,根据实际情况进行替换。执行该命令后,NuGet 会读取.nuspec文件中的配置信息,并将项目打包成 NuGet 包。

\4. 打包结果:打包成功后,会在项目目录下生成一个以.nupkg为后缀的文件,例如 “MathLibrary.1.0.0.nupkg”。这个文件就是打包好的 NuGet 包,它包含了库的代码文件、元数据以及其他相关资源。

\5. 文件用途:生成的 NuGet 包可以发布到私有或公共的 NuGet 仓库中,供其他开发人员使用。其他开发人员可以通过 NuGet 包管理器,在他们的项目中轻松安装和引用这个包,而无需手动复制代码文件。例如,在 Visual Studio 中,开发人员可以通过 “管理 NuGet 程序包” 选项,搜索并安装发布的 NuGet 包,然后在项目中使用其中的功能。这样,通过打包和发布 NuGet 包,实现了代码的高效共享和复用,提高了开发效率 。

七、总结与展望

在本文中,我们详细介绍了创建和打包.NET Standard 库的完整流程。从前期准备工作,包括搭建开发环境和了解相关概念,到使用 Visual Studio 或 dotnet CLI 创建项目,接着编写库代码并对其进行测试,最后通过安装 NuGet 打包工具、配置 NuSpec 文件将库打包成 NuGet 包,每一个步骤都至关重要。通过这些步骤,我们能够将自己编写的代码封装成一个可复用的库,方便在不同的项目和平台中使用。

创建和打包.NET Standard 库是.NET 开发中非常实用的技能,它不仅能够提高代码的复用性,减少重复开发的工作量,还能增强代码的可维护性和可扩展性。在实际项目中,你可以将一些通用的业务逻辑、工具方法等封装成.NET Standard 库,然后在多个项目中引用,这样可以大大提高开发效率,降低项目成本。

对于未来的学习方向,你可以进一步深入研究.NET Standard 库的高级特性,如如何优化库的性能、如何处理库的版本兼容性问题等。同时,随着.NET 技术的不断发展,新的功能和特性也在不断涌现,关注.NET 的官方文档和社区动态,学习最新的技术和最佳实践,将有助于你不断提升自己的开发水平。此外,还可以探索如何将.NET Standard 库与其他技术栈进行集成,如结合云服务实现更强大的功能,或者在跨平台移动应用开发中发挥更大的作用 。

希望本文能够帮助你掌握创建和打包.NET Standard 库的方法,并鼓励你在实际项目中积极应用。如果你在实践过程中遇到任何问题,欢迎在评论区留言交流,让我们一起共同进步。

相关文章:

解锁.NET Standard库:从0到1的创建与打包秘籍

一、引言 在当今的软件开发领域&#xff0c;跨平台开发已成为一种趋势。随着不同操作系统和设备的多样化&#xff0c;开发人员需要确保他们的代码能够在多个平台上运行&#xff0c;以满足更广泛的用户需求。.NET Standard 库应运而生&#xff0c;它定义了一组公共 API&#xf…...

Mac 查看 Java SDK 和 Android SDK 的路径

1. Mac 如何查看 JavaSDK的路径 /usr/libexec/java_home -V2. Mac 如何查看 Android SDK 的路径 在 Android Studio 中按 cmd,打开设置&#xff0c;然后如下方式&#xff0c;第三步如果有值就是第三步的信息。 第三步如果没有值&#xff0c;点开Edit&#xff0c;值在下方&…...

6. 马科维茨资产组合模型+政策意图AI金融智能体(DeepSeek-V3)增强方案(理论+Python实战)

目录 0. 承前1. 幻方量化 & DeepSeek1.1 What is 幻方量化1.2 What is DeepSeek 2. 重写AI金融智能体函数3. 汇总代码4. 反思4.1 不足之处4.2 提升思路 5. 启后 0. 承前 本篇博文是对上一篇文章&#xff0c;链接: 5. 马科维茨资产组合模型政策意图AI金融智能体(Qwen-Max)增…...

freeswtch目录下modules.conf各个模块的介绍【freeswitch版本1.6.8】

应用模块&#xff08;applications&#xff09; mod_abstraction&#xff1a; 为其他模块提供抽象层&#xff0c;有助于简化模块开发&#xff0c;让开发者能在统一框架下开发新功能&#xff0c;减少与底层系统的直接交互&#xff0c;提高代码可移植性和可维护性。 mod_av&#…...

Spark/Kafka

文章目录 项目地址一、Spark1. RDD1.1 五大核心属性1.2 执行原理1.3 四种创建方式二、Kafka2.1 生产者(1)分区器(2)生产者提高吞吐量(3) 生产者数据可靠性数据传递语义幂等性和事务数据有序2.2 Broker(1)Broker工作流程(2)节点服役和退役2.3 副本(1)Follower故障细…...

【Linux】华为服务器使用U盘安装统信操作系统

目录 一、准备工作 1.1 下载UOS官方系统 &#xff11;.&#xff12;制作启动U盘 1.3 服务器智能管理系统iBMC 二、iBMC设置U盘启动 一、准备工作 1.1 下载UOS官方系统 服务器CPU的架构是x86-64还是aarch64&#xff09;,地址&#xff1a;统信UOS生态社区 - 打造操作系统创…...

数据库性能优化(sql优化)_SQL执行计划02_yxy

数据库性能优化_SQL执行计划详解02 常用操作符解读1.1 表扫描类型操作符1.1.1 CSCN 聚集索引扫描1.1.2 CSEK 聚集索引数据定位1.1.3 SSEK 二级索引数据定位1.1.4 SSCN 直接使用二级索引进行扫描1.2 其他常见操作符1.2.1 BLKUP 二次扫描1.2.2 SLCT 选择1.2.3 PRJT 投影1.2.4 NSE…...

02.05、链表求和

02.05、[中等] 链表求和 1、题目描述 给定两个用链表表示的整数&#xff0c;每个节点包含一个数位。 这些数位是反向存放的&#xff0c;也就是个位排在链表首部。 编写函数对这两个整数求和&#xff0c;并用链表形式返回结果。 2、解题思路 本题要求对两个链表表示的整数…...

FPGA实现光纤通信(3)——光纤8b/10b编码数据回环

前言 光纤通信属于高速串行通信,具有较高的数据传输速率,通常用于服务器以及通信设备之间用于高速数据交换,对于xilinx 7系列的FPGA,内部具有集成的高速接口用于实现光纤通信。本次就来实现8b/10b编码数据回环。 测试环境:vivado版本:2020.02 FPGA芯片:XC7K70T 测试说…...

Python!从0开始学爬虫:(一)HTTP协议 及 请求与响应

前言 爬虫需要基础知识&#xff0c;HTTP协议只是个开始&#xff0c;除此之外还有很多&#xff0c;我们慢慢来记录。 今天的HTTP协议&#xff0c;会有助于我们更好的了解网络。 一、什么是HTTP协议 &#xff08;1&#xff09;定义 HTTP&#xff08;超文本传输协议&#xff…...

神经网络基础详解

神经元结构 在探讨神经网络的基础时,神经元结构是一个关键概念。神经元是神经网络的基本组成单元,模拟了生物神经元的功能。其结构包括: 细胞体 :负责处理和整合输入信息 树突 :接收来自其他神经元的输入信号 轴突 :将处理后的信息传递给其他神经元 神经元通过加权求和和…...

使用Chrome和Selenium实现对Superset等私域网站的截图

最近遇到了一个问题&#xff0c;因为一些原因&#xff0c;我搭建的一个 Superset 的 Report 功能由于节假日期间不好控制邮件的发送&#xff0c;所以急需一个方案来替换掉 Superset 的 Report 功能 首先我们需要 Chrome 浏览器和 Chrome Driver&#xff0c;这是执行数据抓取的…...

2025展望:“安全计算”平价时代加速到来,数据流通产业兴起

大数据产业创新服务媒体 ——聚焦数据 改变商业 2024年&#xff0c;数据要素产业元年开启。 这是建章立制的一年&#xff1a;从年初《“数据要素”三年行动计划&#xff08;2024—2026年&#xff09;》开始&#xff0c;这一年政策密集出台&#xff0c;涵盖公共数据资源开发利用…...

达梦拷贝DM_HOME的复制安装

近期一个项目需求&#xff0c;需要在没有安装包的情况下&#xff0c;将达梦数据库安装到虚机上&#xff08;生产机上安装了达梦&#xff09;&#xff0c;故采用直接打包生产机DM_HOME的方式拷贝至虚机&#xff0c;再依次执行达梦的部分指令完成安装。以下为验证的步骤&#xff…...

九、CSS工程化方案

一、PostCSS介绍 二、PostCSS插件的使用 项目安装 - npm install postcss-cli 全局安装 - npm install postcss-cli -g postcss-cli地址&#xff1a;GitHub - postcss/postcss-cli: CLI for postcss postcss地址&#xff1a;GitHub - postcss/postcss: Transforming styles…...

二叉树的最大深度(C语言详解版)

一、摘要 嗨喽呀大家&#xff0c;leetcode每日一题又和大家见面啦&#xff0c;今天要讲的是104.二叉树的最大深度&#xff0c;思路互相学习&#xff0c;有什么不足的地方欢迎指正&#xff01;好啦让我们开始吧&#xff01;&#xff01;&#xff01; 二、题目简介 给定一个二…...

深入探索imi框架:PHP Swoole的高性能协程应用实践

摘要 本文将介绍 imi 框架&#xff0c;这是一个基于 PHP Swoole 的高性能协程应用开发框架。imi 支持 HttpApi、WebSocket、TCP 和 UDP 等多种服务类型&#xff0c;利用 Swoole 的优化技术&#xff0c;使得在处理请求时响应速度远超传统的 php-fpm 方式。通过丰富的代码示例&a…...

机器学习-线性回归(参数估计之经验风险最小化)

给定一组包含 &#x1d441; 个训练样本的训练集 我们希望能够 学习一个最优的线性回归的模型参数 &#x1d498; 现在我们来介绍线性回归的一种模型参数估计方法&#xff1a;经验风险最小化。 我们前面说过&#xff0c;对于标签 &#x1d466; 和模型输出都为连续的实数值&…...

使用 Elasticsearch 导航检索增强生成图表

作者&#xff1a;来自 Elastic Louis Jourdain 及 Ivan Monnier 了解如何使用知识图谱来增强 RAG 结果&#xff0c;同时在 Elasticsearch 中高效存储图谱。本指南探讨了根据用户查询动态生成知识子图的详细策略。 检索增强生成 (RAG) 通过将大型语言模型 (LLM) 的输出基于事实数…...

Flutter调用HarmonyOS NEXT原生相机拍摄相册选择照片视频

目录 1.项目背景 2.遇到的问题 3.开发准备 4.开发过程 首先创建注册调用鸿蒙原生的渠道 创建并初始化插件 绑定通道完成插件中的功能 5.具体步骤 根据传值判断是相册选取还是打开相机 相册选取照片或视频 相机拍摄照片或视频 调用picker拍摄接口获取拍摄的结果 视频…...

浅析云场景SSD实时迁移技术

在数据中心的运营管理中&#xff0c;负载均衡和系统容错是确保高效稳定运行的关键。SSD实时迁移技术&#xff0c;为解决这些问题提供了创新方案&#xff0c;成为数据中心技术发展的重要驱动力。 以AI训练任务为例&#xff0c;其运行时间长且无需用户频繁交互。数据中心的负载会…...

WordPress Hunk Companion插件节点逻辑缺陷导致Rce漏洞复现(CVE-2024-9707)(附脚本)

免责申明: 本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 0x0…...

BGP分解实验·11——路由聚合与条件性通告(3)

续接上&#xff08;2&#xff09;的实验。其拓扑如下&#xff1a; 路由聚合的负向也就是拆分&#xff0c;在有双出口的情况下&#xff0c;在多出口做流量分担是优选方法之一。 BGP可以根据指定来源而聚合路由&#xff0c;在产生该聚合路由的范围内的条目注入到本地BGP表后再向…...

SQL Server 使用SELECT INTO实现表备份

在数据库管理过程中&#xff0c;有时我们需要对表进行备份&#xff0c;以防数据丢失或修改错误。在 SQL Server 中&#xff0c;可以使用 SELECT INTO 语句将数据从一个表备份到另一个表。 备份表的 SQL 语法&#xff1a; SELECT * INTO 【备份表名】 FROM 【要备份的表】 SEL…...

RPC是什么?和HTTP区别?

RPC 是什么&#xff1f;HTTP 是什么&#xff1f; 作为一个程序员&#xff0c;假设我们需要从A电脑的进程发送一段数据到B电脑的进程&#xff0c;我们一般会在代码中使用 Socket 进行编程。 此时&#xff0c;可选性一般就是 TCP 和 UDP 二选一&#xff0c;由于 TCP 可靠、UDP 不…...

西藏酥油茶:高原上的醇香温暖

西藏酥油茶:高原上的醇香温暖 在西藏高原,有一种饮品,它不仅滋养了一代又一代的藏民,还承载着丰富的文化与历史,它就是西藏酥油茶。酥油茶,藏语称为“恰苏玛”,意为搅动的茶,是藏族人民日常生活中不可或缺的一部分,更是待客、祭祀等活动中的重要礼仪物品。 历史与文化渊源 酥…...

十、VUE中的CSS

一、vue中解决样式不冲突的两种方式 scoped方式 在App.vue中引入Helloworld子组件 在Helloworld子组件中再次引入我们编写Demo子组件 解释&#xff1a; 这种方式是在style上加了个scoped,限制了样式的使用范围。 动态类名方式 二、vue构建打包 npm run build...

论文阅读 AlphaFold 2

用AlphaFold进行非常精确的蛋白质结构的预测(AlphaFold2) 发表于2021年07月15日 NatureDOI: 10.1038/s41586-021-03819-2自然和科学杂志评选为2021年最重要的科学突破之一2021年AI在科学界最大的突破 前言 2020年11月30号, deepmind博客说AlphaFold解决了50年以来生物学的大挑…...

PVE 虚拟机安装 Debian 无图形化界面服务器

Debian 安装 Debian 镜像下载 找一个Debian镜像服务器&#xff0c;根据需要的版本和自己硬件选择。 iso-cd/&#xff1a;较小&#xff0c;仅包含安装所需的基础组件&#xff0c;可能需要网络访问来完成安装。有镜像 debian-12.9.0-amd64-netinst.isoiso-dvd/&#xff1a;较…...

讯飞星火大模型将超越chatgpt?

讯飞星火大模型真的能超越ChatGPT吗? 在人工智能的世界里,新技术层出不穷,而科大讯飞最近发布的讯飞星火大模型3.0引发了不少讨论。有些人甚至大胆猜测:这个模型是否能够在某些方面超越如今广受欢迎的ChatGPT?今天,我们就来深入探讨一下这个话题,分析讯飞星火大模型3.0…...

Linux解决输入法卡死问题

说明&#xff1a;在Ubuntu系统中&#xff0c;如果您需要重启输入法服务&#xff08;比如fcitx或ibus&#xff09;&#xff0c;您可以按照以下步骤操作。这些步骤适用于大多数基于Ubuntu的发行版&#xff0c;例如Ubuntu、Linux Mint等。 一、重启Fcitx输入法服务 1、使用Ctrl …...

PPT自动化 python-pptx -7: 占位符(placeholder)

占位符&#xff08;placeholder&#xff09;是演示文稿中用于容纳内容的预格式化容器。它们通过让模板设计者定义格式选项&#xff0c;简化了创建视觉一致幻灯片的过程&#xff0c;同时让最终用户专注于添加内容。这加快了演示文稿的开发速度&#xff0c;并确保幻灯片之间的外观…...

“AI视觉贴装系统:智能贴装,精准无忧

嘿&#xff0c;朋友们&#xff01;今天我要跟你们聊聊一个特别厉害的技术——AI视觉贴装系统。这可不是普通的贴装设备&#xff0c;它可是融合了人工智能、计算机视觉和自动化控制等前沿科技的“智能贴装大师”。有了它&#xff0c;那些繁琐、复杂的贴装工作变得轻松又精准。来…...

【Efficient AIGC】SiTo: Similarity-based Token Pruning (AAAI-2025)

文章目录 SiTo: Training-Free and Hardware-Friendly Acceleration for Diffusion Models via Similarity-based Token Pruning背景介绍方法结果消融 文章目录 SiTo: Training-Free and Hardware-Friendly Acceleration for Diffusion Models via Similarity-based Token Prun…...

音频入门(一):音频基础知识与分类的基本流程

音频信号和图像信号在做分类时的基本流程类似&#xff0c;区别就在于预处理部分存在不同&#xff1b;本文简单介绍了下音频处理的方法&#xff0c;以及利用深度学习模型分类的基本流程。 目录 一、音频信号简介 1. 什么是音频信号 2. 音频信号长什么样 二、音频的深度学习分…...

mac 通过 Homebrew 安装 git 遇到的问题

问题真多啊 &#xff01;&#xff01;&#xff01; 解决方式 见 1. / 2. / 3 . / 4. / 5. remote: Enumerating objects: 290323, done. remote: Counting objects: 100% (473/473), done. remote: Compressing objects: 100% (253/253), done. error: RPC failed; curl 92 H…...

Flutter android debug 编译报错问题。插件编译报错

下面相关内容 都以 Mac 电脑为例子。 一、问题 起因&#xff1a;&#xff08;更新 Android studio 2024.2.2.13、 Flutter SDK 3.27.2&#xff09; 最近 2025年 1 月 左右&#xff0c;我更新了 Android studio 和 Flutter SDK 再运行就会出现下面的问题。当然 下面的提示只是其…...

【信息系统项目管理师-选择真题】2018上半年综合知识答案和详解

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 【第1题】【第2题】【第3题】【第4题】【第5题】【第6题】【第7题】【第8题】【第9题】【第10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18题】【第19题】【第20题】【第…...

探究 Facebook 隐私安全发展方向,未来走向何方?

随着社交媒体的普及&#xff0c;隐私和数据安全问题成为了全球关注的焦点。Facebook&#xff0c;作为全球最大的社交平台之一&#xff0c;其隐私安全问题尤其引人注目。近年来&#xff0c;随着用户数据泄露事件的不断发生&#xff0c;Facebook 不断调整其隐私政策&#xff0c;探…...

漏洞修复:Apache Tomcat 安全漏洞(CVE-2024-50379) | Apache Tomcat 安全漏洞(CVE-2024-52318)

文章目录 引言I Apache Tomcat 安全漏洞(CVE-2024-50379)漏洞描述修复建议升级Tomcat教程II Apache Tomcat 安全漏洞(CVE-2024-52318)漏洞描述修复建议III 安全警告引言 解决方案:升级到最新版Tomcat https://blog.csdn.net/z929118967/article/details/142934649 service in…...

Leecode刷题C语言之购买水果需要的最小金币数

执行结果:通过 执行用时和内存消耗如下&#xff1a; int dp(int* prices, int pricesSize, int index, int* memo) {if (2 * index 2 > pricesSize) {return prices[index];}if (memo[index] -1) {int minValue INT_MAX;for (int i index 1; i < 2 * index 2; i) …...

【27】Word:徐雅雯-艺术史文章❗

目录 题目​ NO1.2 NO3 NO4 NO5 NO6.7 NO8.9 NO10.11 注意&#xff1a;修改样式的字体颜色/字号&#xff0c;若中英文一致&#xff0c;选择所有脚本。格式相似的文本→检查多选/漏选格式刷F4重复上一步操作请❗每一步检查和保存 题目 NO1.2 F12另存为布局→行号布局…...

MySQL日志详解——日志分类、二进制日志bin log、回滚日志undo log、重做日志redo log

文章目录 一、前言1.1 MySQL体系结构1.2 MySQL日志分类1.3 其他几种日志1.3.1 查询日志1.3.2 慢查询日志1.3.3 错误日志 二、bin log 二进制日志2.1 bin log简介2.2 binlog日志格式2.3 日志删除2.4 写入/刷盘机制 三、undo log 回滚日志3.1 undo log简介3.2 隐藏字段 —— 事务…...

数字MIC PDM接口

在音频采样中&#xff0c;我们经常会用到PCM&#xff0c;PDM这种方式&#xff0c;它们之间也是有一些区别的。 &#xff11;&#xff1a;PDM 工作原理&#xff1a; PDM使用远高于PCM采样率的时钟采样调制模拟分量&#xff0c;每次采样结果只有1位输出&#xff08;0或1&…...

dfs专题五:FloodFill算法

1.图像渲染 link:733. 图像渲染 - 力扣&#xff08;LeetCode&#xff09; code class Solution { public:int prev;vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {if(image[sr][sc] color) return …...

笔试-二维数组

应用 快递业务有N个站点&#xff0c;1<N<10000&#xff1b;站点0、站点1可达&#xff0c;记作0-1&#xff1b;如果0-1、1-2&#xff0c;则站点0、站点2可达&#xff0c;记作0-2&#xff1b;s[i][j]1表示i-j可达&#xff0c;反之s[i][j]0表示i-j不可达&#xff1b;s[i][j…...

大模型GUI系列论文阅读 DAY2续:《一个具备规划、长上下文理解和程序合成能力的真实世界Web代理》

摘要 预训练的大语言模型&#xff08;LLMs&#xff09;近年来在自主网页自动化方面实现了更好的泛化能力和样本效率。然而&#xff0c;在真实世界的网站上&#xff0c;其性能仍然受到以下问题的影响&#xff1a;(1) 开放领域的复杂性&#xff0c;(2) 有限的上下文长度&#xff…...

如何提升IP地址查询数据服务的安全?

随着网络科技深入人们的生活之中&#xff0c;数据相关服务顺时代浪潮应运而生。而在数据查询相关服务之中&#xff0c;数据安全乃是重中之重。而如何部署数据查询服务安全&#xff0c;今天让我们来大致了解一下&#xff1a; 数据加密 数据加密是数据查询服务安全的核心技术之…...

【Leetcode】--- 接雨水

题目传送门 方法一&#xff1a; 前缀和后缀和 算法原理 需要两个数组。 第一个数组存储最左边到第 i 个位置的最大高度&#xff08;前缀最大值&#xff09; 第二个数组存储最右边到第 i 个位置的最大高度&#xff08;后缀最大值&#xff09; 最终第 i 个位置的 接水量 min&am…...

深入探索Math.NET:开启高效数值计算之旅

一、引言 在当今数字化时代&#xff0c;数值计算已然成为科学研究、工程设计、金融分析等众多领域的核心驱动力。从探索宇宙奥秘的物理学计算&#xff0c;到优化建筑结构的土木工程设计&#xff0c;再到预测市场趋势的金融建模&#xff0c;数值计算的身影无处不在&#xff0c;…...