前言
每个人都有自己习惯的项目结构,有些人喜欢在项目中构建解决方案文件夹;有人喜欢传统的三层命名;有些人喜欢一个简单的项目,可以用一个csproj来完成。
反正是萝卜青菜,各有所爱。
不同的公司可能对这些有特定的要求,或者他们可能通过发展自己的想法来实践。
然后,问题来了。如果有一个新项目,你会如何创建?
可能还有以下三种方式:
简单粗暴,打开VS意味着右键添加,然后引入一堆包,添加每个项目的引用。脚本类型,基于dotnet cli,创建解决方案,创建项目,添加包和添加项目引用。高大且最新的,vs项目模板,直接集成到VS中过去我也是基于dotnet cli编写sh或者ps脚本,然后用这些脚本生成新的项目。
然而,这三种方法总是不能令人满意。
因为所有构建的模板都是空的,所以需要大量复杂的操作才能使项目正常运行。例如,这个公共类应该被复制,那个公共类应该被复制。这显然是浪费时间。
这里有一个节省你时间的小方法。
基于dotnet cli创建自己的项目模板,这通常称为脚手架。
dotnet cli项目的模板预热
在进入正题之前,让我们看一下dotnet cli附带的一些模板。
可以看出有很多种。由于大部分工作时间都用于编写WebAPI,因此我们将在这里使用WebAPI编写一个简单的模板。
然后我们将基于dotnet cli编写自己的模板。
编写自己的模板
既然是模板,就一定要有一个样本项目。
让我们构建一个示例项目,大致是这样的,这样每个人都可以遵循自己的习惯。
这其实是一个普通的项目,其中加入了NLog、Swagger、Dapper等组件,每个项目的引用关系都建立得很好。
还包括了一些公共类,比如Yunei共享的WebHostBuilderJexusExtensions。
下面是这个模板运行的效果。
是一个简单的斯瓦格页面。
现在我们有了一个样本,如何把这个样本变成模板呢?
答案是template.json!
创建一个文件夹。然后在这个文件夹下创建template.json。
例子如下:
{'author': 'Catcher Wong ',//必须' classions ' :[' web/web API '],//必须,此对应模板的标记' name' :' tpldemo ',//必须,此对应模板的模板' identity' :' tpldemotemplate ',//可选,模板的唯一名称' shortName': 'tpl ',//必选,short name ' tags ' : { ' language ' 3: '
ShortName,简称short,是懒惰的必备之物。例如,如果您可以写-h,就不应该写-helpsourcename。这是一个可选字段,其值将替换指定的项目名称。通常,项目名称将在此处指定。如果未指定,则创建的项目与示例项目一致。写完template.json之后,我们需要将这个模板安装到我们的cli中。
使用dotnet new -i安装模板。
下面是一个安装示例。
Dotnet new -i ./content/TplDemo这里需要注意的是,目录与。template.config文件夹将被打包成模板。
执行安装命令后,我们可以看到我们的模板已经安装好了。
我迫不及待地想在这个时候尝试这个模板。
我们先来看看这个模板的帮助信息。
dotnet新TPL-h
因为我们还没有设置参数,这里显示没有参数。
让我们尝试创建一个项目。
从创建项目到运行,非常简单,效果也是我们所期待的。
让我们看看这个新的HelloTpl项目的目录结构是否与我们的模板相同。
可以看出,除了名字,一切都是一样的。
你觉得可以少复制粘贴很多代码吗?
虽然现在一个大模板建一个项目完全可以复制,但是一直都不是很灵活!
有些朋友可能会问,为什么在很方便的时候还说不灵活?
慢慢听我说。
如果这个模板是一个大而全的模板,它包含了中间件A、中间件B、中间件C等n个中间件!
在构建一个新项目的时候,已经明确只使用了中间件A,所以其他的中间件对我们来说可能没有什么意义!
很多时候,您不希望这些冗余文件出现在代码中。有办法控制他们吗?
答案是肯定的!你可以删除不必要的文件。
文件过滤
模板项目中有一个RequestLogMiddleware,所以以它为例。
我们只需要做以下几件事。
第一步是向template.json添加一个过滤器
添加名为EnableRequestLog的符号。还要指定源文件
{ '作者' : '捕手王',//其他.符号' 3360 {//是否启用中间件' enablerequest log ' 3360 { ' type ' : ' parameter ',//它是参数' dataType':'bool ',//bool ',//bool类型的参数' defaultValue': 'false' //默认情况下未启用}},' sources ' 3360[{ ' modifiers ' :[{ ' condition ' : '(。enablerequestlog)',//条件,由EnableRequestLog参数' exclude':确定[//排除以下文件' Src/tpldemo/middleware/requestlogmiddleware . cs ',Src/tpldemo/middleware/requestlogservicecollectionextensions . cs ']}]} }步骤2,在模板的代码中做一些处理
主要是Startup.cs,因为这里启用了中间件。
使用系统;//其他使用.使用TplDemo。核心;#if (EnableRequestLog)使用TplDemo。中间件;#endif ///summary ///////summary公共类Startup { public void Configure(IApplicationBuilder app,IHostingEnvironment env){//其他代码.# if(EnableRequestLog)//请求日志app。UseRequestLog();#endif app。UseMvc(routes={ routes。MapRoute(name: 'default ',template : ' { controller=Home }/{ action=Index }/{ id?}');});}}在这种情况下,只要EnableRequestLog为真,就可以包含这两个代码。
更新下面安装的模板。
此时查看它的帮助信息,您已经可以看到我们添加的参数。
首先,创建一个默认值(未启用请求日志)
命令dotnet new tpl -n NoLog相当于
Dotnet new tpl -n WithLog -E false以下是目录结构和构建后的Startup.cs。
可以看到,与RequestLog相关的一切都消失了。
创建另一个启用了RequestLog的,看看它是否真的有效。
dotnet新tpl -n,带有LOg-E true
可以看到,效果已经出来了。
下面介绍一个有用的特性。动态切换,其实和上面介绍的内容差不多。
动态切换
我们直接举个例子。
假设我们的模板支持MSSQL、MySQL、PgSQL和SQLite数据库操作
构建新项目时,您只需要其中一个。例如,如果你想构建一个PgSQL,你肯定不想看到其他三个。
这里不想看,有两个地方,一个是nuget包的引用,一个是代码。
在最后一部分,一个特定的功能被打开和关闭。这里有四个。我们做什么呢
我们可以通过类型选择的参数来实现。
修改template.json并添加以下内容
{ 'author': 'Catcher Wong ',//others ' symbols ' : { ' sqlType ' : { ' type ' : ' parameter ',' datatype': 'choice ',' choice ' :[{ ' choice ' : ' MsSQL ',' description ' 3: ' MS SQL Server ' },{ ' choice ' 3: ' MySQL ' },{ ' description ' PGSQL ')'},' SQLite ' : { ' Type ' : ' Computed ',' Value ' : '(SQLType== ' SQLite ')' } }看完上面的JSON内容,相信大家都知道原因了。 有一个名为sqlType的参数,它有几个数据库选项,默认为MsSQL。
此外,定义了几个计算参数,它们的值与sqlType的值密切相关。
代码中还使用了MsSQL、MySQL、PgSQL和SQLite四个参数!
修改csproj文件,使其可以根据sqlType动态引用nuget包。我们添加以下内容
ItemGroup条件=' ' $(MySQL)'=' True ' ' package reference Include=' MySQL connector ' Version=' 0 . 47 . 1 '/item GrouP item GrouP条件=' ' $(pgSql)'=' True ' ' package reference Include=' NpgSql ' Version=' 4 . 0 . 3 '/item GrouP item GrouP条件=' ' $(SqLite)=' True ' '包引用include=' Microsoft。数据。SQLite ' version=' 2 . 1 . 0 '/item group同样,应该相应地处理代码
#if (MsSQL)使用系统。Data . SqlClient#elif (MySQL)使用MySQL。数据. MySqlClient#elif (PgSQL)使用Npgsql#其他人使用微软。Data . Sqlite#endif受保护的DbConnection GetDbConnection(){ # if(MSSqL)返回新的SqL connection(_ ConStr);#elif (MySQL)返回新的MySQL connection(_ ConStr);#elif (PgSQL)返回新的npgsqlConnection(_ ConStr);#else返回新的SqLiteConnection(_ Connstr);#endif}修改后,也应该重新安装模板。安装后,可以看到参数sqlType。
下面分别创建一个MsSQL和PgSQL项目进行比较和验证。
连续执行
dotnet new TPL-n mssqltest-s mssqldotnet new TPL-n pgsqltest-s pgsql,然后打开相应的csproj
如您所见,nPgSQL的包已经添加到PgSQL中。而MsSQL没有。
同样,DapperRepositoryBase也有同样的效果。创建连接对象时,它们是根据模板生成的。
当然,这是本地安装的模板,其他人无法使用。
如果你想公开,你可以在nuget上发布。如果在公司内部共享,您可以构建一个内部nuget服务,并将模板上传到内部服务器。
这里有一些现成可用的模板:https://dotnetnew.azurewebsites.net/
摘要
有自己的项目模板(脚手架)非常方便。
一旦您构建了您需要的东西,您就可以减少不必要的代码重复,并更加专注于业务实现。
平时,应该有一些积累。当积累足够丰富的时候,我们的脚手架可能会变得非常强大。
参考文件
dotnet new下的默认模板https://github.com/aspnet/Templating
模板源代码https://github.com/dotnet/templating
template . JSON https://github.com/dotnet/templating/wiki/reference-for-template . JSON的描述
dotnet cli选项卡的文档https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet?=netcore 21
最后给出了本文的示例代码
模板
以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。