从壹开始前后端分离 39 || 想创建自己的dotnet模板么?看这里

缘起

开工是利啦!哈喽各位小伙伴,周三好呀,新的一年又开始了,老张给大家做个榜样,新的一年也要好好学习哟,这两天闲的无事就整理整理了这个系列的 Github 代码,增加了一个英文的 README ,然后把 netcore2.0 合并到了项目里,并新建了一个2.0的分支,相信有些小伙伴应该也发现了,本来想试试 core 3.0版本,发现必须要安装 Visual Studio 2019 版本,可怜电脑已经安装了 vs15 和 vs17,所以就放弃了安装vs19,等明年,哦不对,是今年😂微软正式发布3.0的时候,再整理一个分支吧(以后肯定会有新的内容一直更新的)。

image

在整理代码的时候,我想到,上周在《38 ║自动初始化数据库(不定期更新)》中,我把项目的自动创建数据库并添加种子数据的功能给加上了,给大家提供了一个思路,以后大家创建项目可以这么玩儿,个人感觉还是很方便的,于是我就想到了一个问题,应该是只要开发一定时间的小伙伴,都会遇到的问题:

情景:自己经过多年开发的沉淀后,开发出一个属于自己的一套Demo项目,亦或是借鉴别人的项目后,优化了一个。比如我的第一个项目,采用 IService+ IRepository 分层的;或者比如我的第二个项目,采用DDD领域驱动+CQRS模式的。然后我们在别的地方使用的时候(可能是下一个公司),如果还想用自己的模板,也可能是供新入职的同事使用,经常会是以下几个办法,大家看看你属于哪一种:

0、对比着之前的项目结构,在VistulStudio中手动创建一个空的解决方案,从零开始,一点一点搭建。// 麻烦之大,可想而知

1、通过dotnet cli 命令来创建空项目,然后手动。// 会简化一丢丢,但仍需要一层一层的创建类库;

2、把Demo工程代码里拷贝到U盘,或者上传到云盘,然后下载下来,改吧改吧。// 寻找过程很麻烦,依赖代码承载工具;

3、把Demo工程代码 Pull 到 Github 上,在别的地方直接 Clone ,然后改吧改吧。 // 开源出源码,私密性不强;

大家可以看到,上边的这几个办法,都会有这样或那样的问题,快的不方便,方便的太局限。这个时候你会说,这怎么可能天天创建工程,有时候一个项目搭建好了能用一年,当然,这种也是有的,但是总会有新项目的,而且上边的这些都有一个通病,不知道大家是否发现:就是不能快速修改工程名称!举个栗子,我的这个 Github 上的项目,大家下载下来,怎么快速把 Blog.Core 改成 HelloBlog 呢?

这个时候我想到了一个东西,大家平时的时候应该用到过,就是使用 dotnet CLI 创建一个 net core api 项目是怎么做的呢:

<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">// 通过命令行创建 core api项目
dotnet new webapi</pre>

这么创建好了以后,我们就可以自己一点一点的搭建项目了,这个时候我就想,那既然有 webapi 这个模板,我们自定义一个属于自己的一个或多个模板不就行了?!到时候只需要这么简单的输入一行命令,就能生成一套项目,各层明确,引用清晰,能在任何有网的电脑上运行,并且直接就能跑,想想都会感觉很刺激,不是么?!比如这样:

<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">// 通过自定义命令行创建自己的项目
dotnet new 我是模板名称 -n HelloBlog</pre>

好啦,开始今天的讲解 —— 自定义dotnet 模板,很简单,只要你按照我的一步一步往下走,一定会看得懂。如果你看完本文,对你有帮助,请点个赞👍或评论📑哟。

最终的效果是这样的:

image

一、准备自己的Demo项目模板

1、开发一个空的并编译通过的项目

既然咱们要创建一个自定义的 dotnet 项目模板,那就必须自己先有自己的一套Code,有了这套 code,我们才能导入到 dotnet cli 模板库中使用。

今天呢,我就使用咱们的这个Blog.Core 项目了(https://github.com/anjoy8/Blog.Core),如果你想用自己的模板,前提是:

1、必须Code已经成型了,意思就是说,分层清楚,引用明确,只不过没有复杂的内容。

2、必须编译成功,不能有任何错误,否则后边会各种麻烦。

3、尽量能跑起来,就是能显示出界面,当然也不是必要条件,比如如果你新建了控制台程序,是没有web页面的。

4、一般不要把生成的dll文件包含其中,如果你下载我的Github代码,会发现只有400k,因为我把可执行文件都过滤了。

今天呢,我就手把手把咱们的这套代码给原封不动的分发导入到 dotnet 模板库中,比如这样(这是我本机测试的,正式模板会在下文详细说明):

image

除了咱们的这个项目,以后我还会建立一个基于DDD领域驱动设计的 dotnet 模板,这里先留个坑,到时候把命令行放到这里:(dotnet new -i xxxxxxx)

当然你也可以创建一个,如果你的项目比较好,看完这篇文章后,可以在下边留言哟,让大家都使用使用。

因为使用咱们这个项目,所以这一步很简单,注意不要把项目编译后的dll文件包含里边,一方面打包的时候占资源,另一方面可能会出错,

image

那项目源代码准备好了,接下来怎么做呢,别着急,请往下看。

二、将 Demo 模板导入到dotnet模块库中

现在我们就需要把上边准备的项目导入 dotnet 模板了:

1、创建固定格式的源文件和文件夹

在你的电脑任何地方,新建一个模板文件夹temple,用于以后打包多个模板使用,比如我是这样的(尽量按照这个格式来:content文件夹包含code模板):

<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">├── temple // 用来存放所有的模板
│ ├── BlogCoreTemple // BlogCore模板全部内容
│ │ ├── content // 存放Code 项目代码,可直接运行
│ │ │ ├── Blog.Core
│ │ │ ├── .
│ │ │ ├── .
│ │ │ ├── .
│ │ │ ├── Blog.Core.Services
│ │ │ └── Blog.Core.sln
│ │ │
│ │ ├── license // 存放版本许可信息,如果不添加,后边会警告,文章后边会提到
│ │ │ └── license.txt
│ │ │
│ │ └── 其他待定 // 这里文章后边会打包的时候用到
│ │
│ └── DDDTemple // DDD模板信息</pre>

image

2、用于定义模板的配置文件 (template.json)

既然我们要自定义模板,那我们就必须配置,比如作者信息,比如模板名称,要不然dotnet咋知道哪一个模板是你自定义的呢。接下来咱们定义配置文件:

  1. 向源代码项目的根目录添加 .template.config 文件夹(注意是文件夹),到时候与它同级的文件都会被打包。
  2. 在 .template.config 文件夹中,创建 template.json 文件来配置模板。

<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">{ "$schema": "http://json.schemastore.org/template",//template.json 文件的 JSON 架构,可以不要该键值对
"author": "lao zhang", //必填!模板创建者
"classifications": [ "Web/WebAPI" ], //必填,这个对应模板的Tags,其他的比如 [ "Common", "Console" ],
"name": "Blog.Core Dotnet", //必填,这个是模板名,比如ASP.NET Core Web API
"identity": "Blog.Core.Template", //可选,模板的唯一名称
"shortName": "blogcoretpl", //必填,这个对应模板的短名称,比如webapi
"tags": { "language": "C#" , "type":"project" }, "sourceName": "Blog.Core", // 可选,要替换的名字,这个就是模板的项目名,以后新建的时候,会把这个名字替换成其他,比如HelloBlog(警告!这里不要写一些专用词汇,比如app呀,net呀,core之类的)
"preferNameDirectory": true // 可选,添加目录
}</pre>

提示:这个模板被执行分发,添加到 dotnet 模板后,尽量保存好,不要删掉,因为如果删掉后,如果以后想卸载这个本地的模板,就不能了。

若要从本地文件系统卸载模板,需要完全限定路径。 例如,C:\Users<USER>\Documents\Templates\GarciaSoftware.ConsoleTemplate.CSharp 有效。

详细信息可以查看官网:https://docs.microsoft.com/zh-cn/dotnet/core/tools/custom-templates

<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">├── temple // 用来存放所有的模板
│ ├── BlogCoreTemple // BlogCore模板全部内容
│ │ ├── content // 存放Code 项目代码,可直接运行
│ │ │ ├── .template.config // 模板配置文件夹
│ │ │ │ └── template.json // 配置文件
│ │ │ ├── Blog.Core
│ │ │ ├── .
│ │ │ ├── .
│ │ │ ├── .
│ │ │ ├── Blog.Core.Services
│ │ │ └── Blog.Core.sln
│ │ │
│ │ ├── license // 存放版本许可信息,如果不添加,后边会警告,文章后边会提到
│ │ │ └── license.txt
│ │ │
│ │ └── 其他待定 // 这里文章后边会打包的时候用到
│ │
│ └── DDDTemple // DDD模板信息</pre>

image

3、使用文件系统分发

经过上面两步的处理,咱们已经把模板源代码准备好了,并且也按照固定的规则,把配置文件配置好了,接下来就是来分发了,白话就是说:把代码导入到 dotnet 模板里。

这个是很简单的,代码DOS命令窗口,输入命令(注意文件夹的路径):

<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">// 使用文件分发模板, // 注意文件路径:content文件夹的上一级,可以对比上边的截图中的文件夹结构
dotnet new -i D:\myTpl\temple\BlogCoreTemple</pre>

这个时候你会发现,系统中已经有了我们的模板!(我为了区别下文的第二种方法,故意在模板后加了个22)

image

与此对应的,就是卸载了,注意刚刚的那个文件地址不要删了(就是把新建的字母 i 变成了 u):

<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">dotnet new -u D:\myTpl\temple\BlogCoreTemple</pre>

4、使用dotnet新模板创建一个项目

随便找一个其他文件夹,然后执行我们的操作:

image

成功了有没有!是不是很方便!以后我们把我们的项目模板导入到本地的 dotnet 中,就可以很快的搭建一个一模一样的项目(这个时候如果你运行 dotnet run会报错,因为我们解耦了,会找不到service.dll文件,我们手动F6编译即可),而且项目名称也可以自定义是不是很给力!至少我是感觉挺方便的。

但是,我开心了一分钟后,发现了这个方法的一个弊端,聪明的你应该也发现了,因为我们使用的是文件发布,所以我们只能在本机使用(不信的话,你可以在你电脑上执行下这个命令 dotnet new blogcoretpl22,肯定报错),那如果在家里,或者在新的公司,亦或让新来的同事使用这个模板,该如何使用呢,总不能又要重蹈覆辙,开始拷贝代码吧,哦NO!肯定不想这样,作为强迫症的我,肯定感觉不是很爽,那怎么办呢,别慌,下边的方法可以完美的解决这个问题!

三、发布 Demo 项目到 Nuget

1、添加 nuspec 范本文件

在 content 文件夹旁边,添加 nuspec 文件。 nuspec 文件是 XML 清单文件,用于描述包内容,并促进创建 NuGet 包。

重要:感谢小伙伴@ jamee1696 提醒!下边范本文件中的汉字只是我的解释说明,如果你自己做,请千万要去掉,不能带中文字符!

<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;"><?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
<id>Blog.Core.Webapi.Template</id>// nuget包标识,在 nuget.org 或包驻留的任意库中必须是唯一的
<version>1.0.0</version>// 遵循 major.minor.patch 模式的包版本。
<description> Creates a blog core webapi app.// 用于 UI 显示的包的详细说明。
</description>
<authors>Lao zhang</authors>// 包创建者的逗号分隔列表,与 nuget.org 上的配置文件名称一致
<packageTypes>
<packageType name="Template" />// 包类型
</packageTypes>
<license type="file">license\license.txt</license>// 上文提到的许可证信息
</metadata>
</package></pre>

image

2、下载Nuget.exe

上边配置好了,那怎么如何打包呢,现在咱们就需要 nuget.exe 工具了:https://www.nuget.org/downloads ,下载最新的exe文件即可,注意这个不是安装文件,这个需要配合着项目使用,如果你双击是无效的,把下载好的 nuget.exe 拷贝到 nuspec 范本文件同级的目录中:

image

3、生成Nupkg包

文件也配置好了,nuget执行文件也下载好了,接下来咱们就是正式开始打包了:

打开 DOS 命令窗口,进入到当前文件夹,然后直接运行打包命令:(注意打包的文件,是咱们创建的 nuspec 范本文件)

<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">// 执行打包操作,文件地址就是 nuspec 范本地址
nuget pack D:\myTpl\temple\BlogCoreTemple\Blog.Core.Webapi.Template.nuspec</pre>

发现我们以及打包成功:

image
image

注意:这里有小伙伴提示错误nuget 命令行无效 ,你需要在nuget.exe 目录里操作,并且是 CMD 命令窗口,不是 powershell

image

当然你也可以这样:

将文件夹添加到 nuget.exe 中放置 PATH 环境变量的位置,这样就可以从任意位置使用 CLI 工具。

4、发布到nuget.org(注意质量)

提醒下,大家要注意模板的质量,尽量不要过多的上传打包哟。

接下来就是最后一步了,将我们打包成功的 nupkg 包,发布到 nuget.org ,这里有多种方法,我只演示web门户操作:

首先你需要在 nuget.org 官网注册账号,这里不细说,然后点击到上传页面:https://www.nuget.org/packages/manage/upload

  1. 选择 nuget.org 顶部菜单中的“上传”,并浏览到包位置。

    在 nuget.org 上上传包
  2. nuget.org 告知包名称是否可用。 如果无法使用,则更改项目中的包标识符、重新生成,并重试上传。

  3. 如果包名称可用,nuget.org 将打开“验证”部分,可以在其中查看包清单中的元数据。 若要更改任何元数据,请编辑项目(项目文件或 .nuspec 文件)、重新生成、重新创建包,然后再次上传。

  4. 在“导入文档”下,可以粘贴 Markdown、将 URL 指向文档,或上传文档文件。

  5. 当所有信息准备就绪后,选择“提交”按钮

上传成功后,nuget 会后台进行扫描病毒,然后进行发布,中间大概等待10分钟后,你会收到一个官方的邮件,提示你已经发布成功:

地址:https://www.nuget.org/packages/Blog.Core.Webapi.Template/

image

具体的参考官网:https://docs.microsoft.com/zh-cn/nuget/create-packages/publish-a-package#package-validation-and-indexing

四、Nuget包导入到dotnet模板,并创建新工程

1、使用nuget.org 的包ID进行分发

在上边发布成功了以后,我们直接就可以通过 nuget 唯一包id,来进行导入dotnet 模板操作:

<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">// 通过nuget.org ID 导入分发,这个名称,就是我们之前在 nuspec 范本文件中,配置的nuget包 ID
dotnet new -i Blog.Core.Webapi.Template</pre>

然后就可以看到已经导入成功了,至于使用,就和之前的通过文件系统导入的是一样的:

image
image

是不是很不错!完全解放双手,也不依赖工具,就可以直接创建一套相同的项目,并可以自定义项目名:

不信的话,你可以在你电脑里执行下刚刚的那个模板导入命令(dotnet new -i Blog.Core.Webapi.Template),可以成功的导入到你的电脑里(注意一定要是管理员权限打开命令行窗口,如果报错,可能是401权限问题,请在下方留言)。如果你用不了这个命令,证明你的电脑是没有最高权限的,那就请用下边的这个方法吧。

2、直接使用nupkg包来导入

如果你不能直接用 nuget.org 的标识ID来分发模板,那就直接用 nupkg 包导入吧,下载本文中的包:https://www.nuget.org/api/v2/package/Blog.Core.Webapi.Template/1.0.0,或者用上边本地的打包好的,是一样的

然后执行命令:

<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">// 将nupkg 包分发
dotnet new -i E:\my-file\temple\Blog.Core.Webapi.Template.1.0.0.nupkg</pre>

image

3、卸载模板

当然如果你不想要,也可以,很简单,直接执行这个命令就行

<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">// 从 nuget.org 中存储的 NuGet 包卸载模板
dotnet new -u Blog.Core.Webapi.Template</pre>

五、结语

今天咱们主要讲解了如何把自己的源代码Demo项目,分发到 dotnet 模板中;然后又讲解了如何把自己的源代码项目进行 nuget 打包,并发布到 nuget.org 库中;

最后将发布到 nuget 包分发到 dotne 模板中,方便的在任何地方使用。

已经在GitHub 上添加了,大家可以下载看看:

image

然后在Nuget包管理器中,可以找到,只不过这是一个整个工程,大家不用添加到项目里,以后你如果创建一个Tool,可以添加到这里,还记得咱们的ORM么(https://github.com/anjoy8/AZLinli.ORM),我打算把这个提交上去,自己使用。

image

最终的文件结构是这样的:

<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">├── temple // 用来存放所有的模板
│ ├── BlogCoreTemple // BlogCore模板全部内容
│ │ ├── content // 存放Code 项目代码,可直接运行
│ │ │ ├── .template.config // 模板配置文件夹
│ │ │ │ └── template.json // 配置文件
│ │ │ ├── Blog.Core
│ │ │ ├── .
│ │ │ ├── .
│ │ │ ├── .
│ │ │ ├── Blog.Core.Services
│ │ │ └── Blog.Core.sln
│ │ │
│ │ ├── license // 存放版本许可信息,如果不添加,后边会警告,文章后边会提到
│ │ │ └── license.txt
│ │ │
│ │ ├── Blog.Core.Webapi.Template.nuspec // nuget 打包的范本配置文件
│ │ └── nuget.exe // nuget.exe 可执行文件
│ │
│ └── DDDTemple // DDD模板信息</pre>

六、Github & Gitee

https://github.com/anjoy8/Blog.Core

https://gitee.com/laozhangIsPhi/Blog.Core

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容