NuGet是什么?理解与使用(上)

article/2025/10/16 14:13:22

如果你了解python,那么它类似pip。

如果你了解nodejs,那么它类似npm。

如果你了解ruby,那么它类似gem。

对,它就是一个包(package)管理平台,确切的说是 .net平台的包管理工具,它提供了一系列客户端用于生成,上传和使用包(package),以及一个用于存储所有包的中心库即NuGet Gallery,如果有需要也可以搭建自己的私有NuGet库。

NuGet 官方​www.nuget.org

 

对于一个现代化的开发平台,建立一种让开发者创建,分享与使用可复用代码的机制是十分必要的。这种“可复用代码”被打包后的文件通常被称作“包”(package),对于.NET(包括 .NET Core)平台来说这个机制的实现就是NuGet平台。

NuGet的实现均为开源项目,包括了客户端工具,服务器,官方网站以及各语言的文档等。 这些项目可以在下面的链接中找到。

NuGet on GitHub​github.com

 

NuGet包的本质是一个以nupkg为后缀的zip压缩文件(你可以将后缀改为.zip后解压查看里面的内容),其中包含了编译后的Dll文件以及其他相关文件。下图显示nuget包从创建,上传到被使用的流程。

NuGet的客户端融合在各类开发工具中,包括但不限于:

  1. .net core SDK中的nuget命令行;
  2. Visual Studio中的nuget工具;
  3. nuget.exe 命令行客户端;
  4. Visual Studio Code中的nuget插件;

nuget客户端工具

在了解了nuget大致概念后我们可以通过发布一个nuget包来更仔细的了解如何使用nuget以及其中的重要概念。

下文会以开发中最常接触到的Visual Studio( 本文使用Visual Studio 2017 Community )做为演示工具来创建一个nuget包。要创建一个包首先需要一个 .net项目,可以看到项目的创建页面有很多选择,类库项目就可以选择三种(.net core的类库项目未显示在截图中) .Net Core;.Net Framework 还有 .Net Standard,到底应该选择哪一种呢?

Visual Studio 2017 项目创建窗口

为了做出选择,我们首先要深入理解TFMs和 .net standard这两个概念。首先创建一个 .net core类库项目。

.net core类库项目结构

在项目目录中打开csproj文件可以看见下面的内容。

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

可以看到该项目的TargetFramework为netcoreapp2.0,这里的netcoreapp2.0 就是TFMs,即Tagrget Framework Monikers 翻译过来就是“目标框架别名”,这个值指定了这个项目是跑在哪个Framework上的。

如今 .net平台有各种版本的Framework,在 .net core之前有 .Net Framework 1.0一直到现在的4.7等等各种版本, .net core现在有1.0/1.1/2.0/2.1。所有这些版本都有自己的代号/别名。全部的TFMs可以在下面的链接找到。

Target frameworks​docs.microsoft.com图标

这仍然没有解决我们的问题:如何决定使用哪个Framework?现在需要引入 .Net Standard,它是一个标准, .net API的标准,用来描述每个Framework的API实现情况。标准的版本越往后支持的API就越多,也就兼容了之前的版本。

当前各个Framework的 .Net Standard版本如下图(如果你曾经了解Portable Class Libraries(PCL),它已经被 .net standard替代了,所以这里不多做说明。)

最新的内容可以在下面的链接中找到。

dotnet/standard​github.com

 

所以要选择哪个Framework,首先要确定的是:1)你的项目要使用哪些API?2)你项目要兼容哪些Framework? 总的来说:

  1. 选择更高的版本,你将有更多的API可以使用。(更丰富的API)
  2. 选择更低的版本,有更多的项目可以使用你的库。(更好的兼容性)

所以 .net standard的选择原则就是:在API够用的情况下选择尽量低的 .net standard标准。这需要根据实际的项目需求来进行判断。

了解了TFMs和 .net standard后我们绕回来说NuGet,创建一个 .net standard 2.0 类库项目。

打开csproj我们可以看到

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

可以看到TargetFramework是netstandard2.0。如果我们需要更改TargetFraamework,可以选择项目【属性】在【应用程序】页面可以进行更改。

目标框架修改

为了演示我们为项目添加一个第三方包Newtonsoft.Json,右键点击项目选择管理NuGet程序包。

打开后可以在Visual Studio左侧看到下面的界面。

这里显示了项目已安装的包,这个包由我们选择的Target Framework隐式引用的。现在我们点击浏览,搜索Newtonsoft.Json。

120M的下载量,可见现在json的流行程度

点击安装。

安装完成后可以看到程序包管理器输出以下信息,并且引用中也添加了新的项目。

但是我并没有在项目文件夹下找到任何Newtonsoft.Json的程序集,包在哪?其实包被下载到了一个nuget公共目录,在我的Windows10系统上是 C:\Users\wangl\.nuget\packages,这样nuget包就不会被重复下载。而在项目中nuget仅仅将依赖信息写入了csproj项目文件与obj文件夹中的project.assets.json,其中csproj项目文件中的内容如下。

<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>netstandard2.0</TargetFramework></PropertyGroup><ItemGroup><PackageReference Include="Newtonsoft.Json" Version="11.0.2" /></ItemGroup></Project>

包所依赖的内容并不会被打包到最后的.nupkg文件中,NuGet只是将依赖信息写入包,在最终使用这些包的应用程序编译时还原所有的依赖。

至此我们简单了解了NuGet给项目添加引用的过程。对于更复杂情况的引用,如下图

项目引用示例

这个项目的依赖树中有三个对B包的引用,而三个包的版本要求可能是不相同的,但幸好我们只需要关心我们项目直接引用的包,因为Nuget会帮我们管理所有包的依赖并且对于被多次引用的包,Nuget会找出满足该包所有使用者的版本(不过因为版本要求冲突而找不到适合包的情况是有可能的)。如果需要更详细的了解nuget如何解析项目包的引用可以前往下面的链接。

NuGet Package Dependency Resolution​docs.microsoft.com图标

现在开始打包我们的类库项目,首先要为包设置一些诸如版本,作者等相关信息。右键点击项目选择【属性】,再选择【打包】页,可以在这里输入包的描述信息。

打开csproj项目文件,可以看到这些信息也是保存在其中的。

<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>netstandard2.0</TargetFramework><ApplicationIcon /><OutputType>Library</OutputType><StartupObject /><Authors>FishNo6</Authors><Company>FishNo6</Company><Product>DemoPackage</Product><Version>1.0.1</Version><AssemblyVersion>1.0.0.1</AssemblyVersion><FileVersion>1.0.0.1</FileVersion><Description>This package is a demonstration for Nuget package.</Description></PropertyGroup><ItemGroup><PackageReference Include="Newtonsoft.Json" Version="11.0.2" /></ItemGroup></Project>

填写好信息后保存。回到解决方案,右键点击项目选择【打包】,可以看到以下输出。

1>------ 已启动生成: 项目: FishNo6.DemoPackage, 配置: Debug Any CPU ------
1>FishNo6.DemoPackage -> E:\labs\FishNo6.DemoPackage\FishNo6.DemoPackage\bin\Debug\netstandard2.0\FishNo6.DemoPackage.dll
1>已成功创建包“E:\labs\FishNo6.DemoPackage\FishNo6.DemoPackage\bin\Debug\FishNo6.DemoPackage.1.0.1.nupkg”。
========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========

在对应目录就可以找到nupkg包文件了。如果你的电脑安装了NuGet Package Explorer可以直接双击打开包来查看信息,这个应用可以在Window Store中安装。

到此我们成功创建了一个NuGet包。

下篇内容包括如何将包上传到NuGet Gallary(NuGet官方库)以及更深入的了解NuGet平台。

 

最后附上NuGet官方文档。

NuGet Documentation​docs.microsoft.com图标


本文的目的是记录与分享自己的学习过程和个人你的看法。如果对你有任何帮助深感荣幸,若有任何纰漏烦请指正。如有任何问题请在评论里留言,我会尽量解答。


http://chatgpt.dhexx.cn/article/omjP7PPE.shtml

相关文章

NuGet是什么?为什么.NET项目中会有NuGet?如何使用NuGet程序包?

本文首发于码友网 – 《NuGet是什么&#xff1f;为什么.NET项目中会有NuGet&#xff1f;如何使用NuGet程序包&#xff1f;》 概述 大家好&#xff0c;我是专注.NET开发的码友网创建者Rector。 在.NET应用程序编程开发中&#xff0c;开发者通常使用类库来管理、维护属于同一分…

争取一文说透NuGet

一、NuGet是什么? NuGet是一个为大家所熟知的Visual Studio扩展&#xff0c;通过这个扩展&#xff0c;开发人员可以非常方便地在Visual Studio中安装或更新项目中所需要的第三方组件&#xff0c;同时也可以通过NuGet来安装一些Visual Studio的插件等。 二、官网&#xff1a;…

NuGet是什么?理解与使用

如果你了解python&#xff0c;那么它类似pip。 如果你了解nodejs&#xff0c;那么它类似npm。 如果你了解ruby&#xff0c;那么它类似gem。 对&#xff0c;它就是一个包&#xff08;package&#xff09;管理平台&#xff0c;确切的说是 .net平台的包管理工具&#xff0c;它提供…

接口模板 接口文档

接口模板、接口文档、希望解决接口写的乱七八糟的问题 模板下载 word版 excel版

日期+列表+折线图

#1、分析&#xff1a; 1.1日期&#xff1a; 日&#xff1a;选项为日的时候&#xff0c;右边日期选择YYYY-MM-DD,折线图显示当天的24小时 周&#xff1a;选择为周的时候&#xff0c;右边日期选择YYYY-MM-DD,折线图显示当前日期往前6天 月…

如何制作竖线的效果

描述 在很多网页中, 都会有一个小竖线的效果 (如图) . 实现这个小竖线的效果有很多种方法. 在这里记录一下. 方法 1. 通过::after 在元素后面追加一个宽度为1px的元素 .search-box .search span::after {position: absolute;right: -8px;content: "";width: 1p…

前端画竖线

一条竖线的写法 实现原理&#xff1a; 利用浮动,设置width:1px 代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"&g…

html中竖线怎么写,网页中竖线的几种做法

Q&#xff1a;网页中竖线的几种做法 A&#xff1a;1、用水平线做&#xff1a; 一般水平线的是宽长高短 color#000000>&#xff0c;做竖线我们可以反过来宽短高长&#xff0c; width"1"size"1000" color#000000>&#xff0c;怎么样&#xff1f;竖线出…

latex | 表格竖线被截断 、表格中文字靠近上方

表格竖线被截断 使用latex做表格的时候&#xff1a; 用的是三线表&#xff1a;\toprule midrule bottomrule 会出现表格竖线被截断的问题&#xff1a; 解决办法&#xff1a; 把\toprule midrule bottomrule替换成hline即可 表格文字靠近上方 但是这样修改之后会出现另一…

Latex中表格的竖线截断问题

Latex中使用代码 \begin{table}[htbp] \centering \caption{Add caption} \begin{tabular}{|c|c|c|c|} \toprule Avg. Degree & Node No. & Cascade No. & Cascade Length \\ \midrule 3-10 & 300-1000 & 100-500 & 10-20 \\ \bottomrule \end{tabul…

CSS 画一条横线/竖线

作为优秀的java程序员,扎实(la ji )前端水平是我工作的基础 , 所以今天记录一下怎么用css画一条横线/竖线出来 , 以此为笔记, 将来不需要去翻阅别人的代码 废话不多说 笔记开始 #CSS 代码 /*中间的过度的横线*/.link-top {width: 50%;height: 1px;border-top: solid #ACC0D8…

设置文字之间的竖线

1、定义文字 2、css设置样式

Latex 三线表 横线竖线短横线

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.blog.csdn.net] 目录 样式复现 语法解释 以这个图为例&#xff1a; 样式复现 导言区先添加&#xff1a; \usepackage{tabu} % 表格插入 \usepackage{multirow} % 一般用以设计…

echart markLine x轴 两点之间 或 日期之间 的竖线箭头

业务需求是想实现在两个月份之间的一个竖线代表月份启动日期 这个竖线是动态的 。 这里的难点是&#xff1a;x轴是日期 通过坐标找不到日期之间的中间的位置 。 解决方案&#xff1a;因此再创建有个x轴 我这里新的x轴刻度放大了五倍 根据比例找到你画的竖线在新的x轴的位置 &am…

C#中抽象类与抽象方法的详解

前言:在上一篇博文关于重写的前提说明中提到了,那么今天我们一起来看看抽象类以及抽象方法…,首先我们顺着目录从抽象类的介绍开始学习: 目录: 一.抽象类:1.声明形式(创建抽象类):2.抽象类的调用: 二.抽象类的规则:三.抽象方法:四.应用举例:五.抽象类的运用意义;六.总结: 一.抽…

java的抽象方法和抽象类

一个方法&#xff0c;要么是抽象方法&#xff0c;要么必须给出方法的具体实现。 比如我有个animal类&#xff0c;有个吃东西方法&#xff0c;我不希望在animal类中给出这个方法的具体实现&#xff0c;因为不同动物&#xff0c;吃的东西不一样。所以要给这个方法声明为抽象方法…

Java抽象类/抽象方法定义及其特性详解

类的继承结构中&#xff0c;越往上的类越具有通用性&#xff0c;也就越抽象。当它抽象到一定程度&#xff0c;就变成概念成框架&#xff0c;不能再产生实例化的对象了。例如“交通工具”&#xff0c;就无法用它来产生一个实例。 对应这一现象&#xff0c;Java中提供了抽…

Java的抽象类和抽象方法

目录 1、抽象类 2、抽象方法&#xff1a; 3、 抽象类和抽象方法的使用 1、抽象类 当父类的方法不能确定时&#xff0c;可以用abstract关键字来修饰方法&#xff0c;这个方法时抽象方法&#xff0c;用abstract来修饰该类就是抽象类。 public abstract class Animal {public…

抽象类必须要有抽象方法吗?

答案是&#xff1a;不必须。 这个题目主要是考察对抽象类的理解。 说一下我个人的理解吧。 1.如果一个类使用了abstract关键字修饰&#xff0c;那么这个类就是一个抽象类。 2.抽象类可以没有抽象方法 3.一个类如果包含抽象方法&#xff0c;那么这个类必须是抽象类&#xf…