使用GUI工具高效构建你自己的Nuget包丰富包的基础信息添加要包含的文件The end
写这篇文章的原因是我在学习构建nuget包的时候,发现了一个官方推荐的GUI工具,而官方的工具介绍文章已经过时,一些地方和现在最新版本的工具有些差异,所以特意利用假期最后一个下午写下来,希望能帮助更多的人。毕竟,在我看来,从事..NET开发的很多朋友,并不是特别迷恋命令行这种看起来高大上但是实际上并没有高效可言的东西(起码在Windows平台上是这样吧)
下载与安装
您可以导航到这里下载并在线安装这个工具包,我目前没有找到离线安装包,但是索性codeplex不像nuget那么惨,时不时的被…是吧,你懂的!
在安装完成后第一次启动,会检测你使用的是不是windows8系统,如果是会推荐你另外一个windows8应用,当然我个人并不习惯于使用windows8应用在开发机器上(我主要工作也不是开发windows8应用),所以这篇文章将使用最新版本的win32应用做介绍!
起始界面如下所示,比官方文档上那一个版本要酷炫多了,但是不止于酷炫哦
创建nuget工具包
丰富包的基础信息
在点击Create a new package后,是一个简洁的界面
左边部分,可以录入一些包中的基础信息,包括:
包的ID:必须的唯一的ID,格式和C#命名空间规范相同,在你发布包的时候会去验证唯一性。
版本号:必须的三段式的版本号,注意每次发布必须大于上一次的版本号,否则将会被nuget驳回。
标题:非必需的,通常你可以让它和ID保持一致,但是这不是强制的。
作者(s):必须的项目,以逗号分隔作者列表。
拥有者:你可以随便写,但是在发布的时候会被你的nuget帐户名替代。
最低客户端版本:描述这个包限制的最低nuget客户端版本。
iconUrl:一个32*32像素的.png文件地址,作为最终在nuget中显示的图标
描述、标签、许可地址、项目地址,是否强制需要同意许可,这些都一目了然了,不多做介绍。
最后有两项特别重要了;
Dependencies:依赖,这个包是否依赖其它的包,当然你可以把依赖的其他包直接拷贝包含进来,但是这就完全违背了nuget的初衷,如果你所依赖的项目没有nuget包,你可以联系原作者后者帮助打包为nuget包。
Framework Assenbly Reference:这里描述了在安装这个包时会被同时引用的程序集,你可以按照不同的.NET Framework版本区分指定它们。下面给出我自己的包的一个示例:
添加要包含的文件
在最终的nuspec文件中,可以通过设置files的xml节点来逐个指定要包含的文件,但是这样nuget就会完全忽略按照文档结构的约定包含的文件,在大多数情况下,我们不需要去手动指定它,但是在一些特殊的场合,你可能需要使用到它。
files节点可以包含file子节点,它包含src和target两个属性,来分别制定要包含的文件路径和目标路径,在src中还可以使用*和**通配符,想要了解更详细的说明,请参阅http://docs.nuget.org/docs/reference/nuspec-reference.
在nuget文档结构约定中,包含了如下三个文件夹:
lib:包含目标程序将要引用的dll文件。
content:将按照文档结构复制到应用程序根目录中的静态文件,但是如果文件中包含了扩展名是.pp或者transform,那么在将会转换目标文件。
tools:在解决方案或者项目中包含的一些powershell脚本,以及一些可以在Nuget package console中访问的应用程序。(您记得安装完entity framework后的add-migration命令吧,就是由这里提供的),但是powershell的编写已经超出了本文的范围,如果您想了解详细情况,请google之。
在本文示例中,创建了content和lib文件夹
在lib文件夹中,我们可以指令在不同的.net framework版本中,要包含的不同文件的引用,我们可以在任意目录中包含它们,而并不只是在lib文件夹中。
而在添加这些文件夹的时候,可以通过右键点击文件夹,然后选择Add .NET Folder快速的添加不同版本名字缩写的文件夹,这是你使用命令行方式创建nuget包所享受不到的快捷的方式,很酷吧。GUI工具还提供了很多快捷的方式,有待各自探索了。
上文中提到过,党Content文件夹中包含了后缀名为.transform的文件时,nuget将会merge目标文件,比如示例中使用的就是一个ASP.NET MVC扩展的包,它可以提供给ASP.NET MVC生成多选列表和单选列表的HtmlHelper(尽管把这个看成一个硬广吧,地址),所以,我们需要在Visual studio添加这个包的时候,给MVC项目的Views目录下的web.config文件加一个HtmlHelper需要的命名空间记录,所以我编写了如下内容的web.config.transform存放到content/Views目录下
<?xml version="1.0"?>
<configuration>
<system.web.webPages.razor>
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="ListControl.Extension"/>
</namespaces>
</pages>
</system.web.webPages.razor>
</configuration>
当然你也可以定义一些后缀为.pp的文件,来按一定规则生成代码,而且它还可以使用一些预定义的变量,会提供你生成专用于目标项目代码的有效工具。您可以在这里找到更详细的信息。
发布包
最后,使用GUI工具发布包当然是简单的令人发指了,点击工具栏中的File->publish就可以简单的发布你定义的包了,Puslish key来自于你的nuget账户的个人信息页面
使用包
在VS中创建一个项目,打开nuget package窗口,在搜索框中输入上文中定义的包ID:ListControlExtension或者直接在命令行工具中输入命令:Install-Package ListControlExtension,就可以安装并且使用这个扩展了.
上文中的包使用效果:
View文件代码:
<div class="form-group">
@Html.LabelFor(model => model.Departments, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.CheckBoxListFor(model => model.Departments, Model.AllDepartmemtns)
@Html.ValidationMessageFor(model => model.Departments, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Gender, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.RadioButtonListFor(model => model.Gender, Model.GenderCollection,"myCustomStyle")
@Html.ValidationMessageFor(model => model.Departments, "", new { @class = "text-danger" })
</div>
</div>
.
结束语
怎么样?这个GUI工具是不是提供了很多的便捷?(怎么样?这个广告硬的可以把?),如果您喜欢这篇文章,记得在右下角给个“推荐”哦,如果您对上文中的广告的使用效果有什么意见和建议,请不吝拍砖,谢谢
The end
- 独家 | 一文读懂TensorFlow基础
- Webpack中hash与chunkhash的区别,以及js与css的hash指纹解耦方案
- RPC原理及实现
- RMI原理及实现
- webpack多页面开发与懒加载hash解决方案
- 前后端分离和模块化-58到家微信首页重构之路
- Node.js建站笔记-使用react和react-router取代Backbone
- 协同过滤推荐算法Java代码实现
- Nginx模块之Filter解析
- Nodejs建站笔记-注册登录流程的简单实现
- 前端工程化-构建
- [翻译]开发Silverlight 2.0的自定义控件
- LINQ to SQL 辅助工具
- Nginx模块之Upstream解析
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- cJSON,c语言的JSON库!
- 自己动手实现4大免费聊天机器人:小冰、图灵、腾讯、青云客
- Android Spinner下拉框的基本使用
- hadoop本地运行的两个案例。官方Grep案例、官方WordCount案例。
- 腾讯智能闲聊机器人详细开发教程
- 用PyTorch实现MNIST手写数字识别(非常详细)
- 手把手教你从零开始用Java写爬虫
- STM32 cjson的GBK/UTF-8/UNICODE转换、显示中文、GBK字库
- 都说Linux很重要,你会几个Linux命令?来看看这道面试题目。
- 使用VisualGDB将Keil项目导入VisualStudio
- 小白学图像 | Group Normalization详解+PyTorch代码
- 使用VisualGDB开发Keil MDK-ARM项目
- 保姆级教程:还愁不会搭建伪分布式吗?(其实很简单)
- 如何使用OpenCV RTMP直播推流
- Scrapy框架新手入门教程