创建网站的价格,大连住房城乡建设网站,特色的南昌网站建设,wed网站开发是什么前言每个人都有自己习惯的项目结构#xff0c;有人的喜欢在项目里面建解决方案文件夹#xff1b;有的人喜欢传统的三层命名#xff1b;有的人喜欢单一#xff0c;简单的项目一个csproj就搞定。。反正就是萝卜青菜#xff0c;各有所爱。可能不同的公司对这些会有特定的要求… 前言每个人都有自己习惯的项目结构有人的喜欢在项目里面建解决方案文件夹有的人喜欢传统的三层命名有的人喜欢单一简单的项目一个csproj就搞定。。反正就是萝卜青菜各有所爱。可能不同的公司对这些会有特定的要求也可能会随开发自己的想法去实践。那么问题就来了。如果有一个新项目你会怎么去创建可能比较多的方式会是下面三种简单粗暴型打开VS就是右键添加然后引入一堆包每个项目添加引用。脚本型基于dotnet cli创建解决方案创建项目添加包添加项目引用。高大上型VS项目模板直接集成到VS上面了。以前我也是基于dotnet cli写好了sh或ps的脚本然后用这些脚本来生成新项目。但是呢这三种方式始终都有不尽人意的地方。因为建好的都是空模板还要做一堆复杂的操作才可以让项目“正常”的跑起来。比如这个公共类要抄过来那个公共类要抄过来。。。这不是明摆着浪费时间嘛。。。下面介绍一个小办法来帮大家省点时间。基于dotnet cli创建自己的项目模板也就是大家常说的脚手架。dotnet cli项目模板预热开始正题之前我们先看一下dotnet cli自带的一些模板。可以看到种类还是很多的由于工作大部分时间都是在写WebAPI所以这里就用WebAPI来写个简单的模板。下面我们就基于dotnet cli写一个自己的模板。编写自己的模板既然是模板就肯定会有一个样例项目。下面我们建一个样例项目大致成这样大家完全可以按照自己习惯来。这其实就是一个普通的项目里面添加了NLog,Swagger,Dapper等组件各个项目的引用关系是建好的。该有的公共类里面也都包含了好比宇内分享的那个WebHostBuilderJexusExtensions。下面是这个模板跑起来的效果。就是一个简单的Swagger页面。现在样例已经有了要怎么把这个样例变成一个模板呢答案就是template.json在样例的根目录创建一个文件夹.template.config同时在这个文件夹下面创建template.json。示例如下{ author: Catcher Wong, //必须 classifications: [ Web/WebAPI ], //必须这个对应模板的Tags name: TplDemo, //必须这个对应模板的Templates identity: TplDemoTemplate, //可选模板的唯一名称 shortName: tpl, //必须这个对应模板的Short Name tags: { language: C# , type:project}, sourceName: TplDemo, // 可选要替换的名字 preferNameDirectory: true // 可选添加目录
}在这里有几个比较重要的东西一个是shortName一个是sourceName。shortName简写偷懒必备好比能写 -h 就绝对不写 --helpsourceName这是个可选的字段它的值会替换指定的项目名正常是把项目名赋值在这里。如果不指定创建的项目就和样例项目保持一致。在写完template.json之后还需要安装一下这个模板到我们的cli中。使用 dotnet new -i进行模板的安装。下面是安装示例。dotnet new -i ./content/TplDemo这里要注意的是与.template.config文件夹同级的目录都会被打包进模板中。在执行安装命令之后就可以看到我们的模板已经安装好了。这个时候已经迫不及待的想来试试这个模板了。先来看看这个模板的帮助信息。dotnet new tpl -h因为我们目前还没有设置参数所以这里显示的是还没有参数。下面来创建一个项目试试。从创建一个项目到运行起来很简单效果也是我们预期的。下面来看看新建的这个HelloTpl这个项目的目录结构和我们的模板是否一样。可以看到除了名字其他的内容都是一样的。是不是感觉又可以少复制粘贴好多代码了。虽说现在建项目已经能把一个大的模板完整的copy出来了但是始终不是很灵活可能有小伙伴会问明明已经很方便了呀为什么还会说它不灵活呢且听我慢慢道来。如果说这个模板是个大而全的模板包含了中间件A中间件B中间件C等N个中间件而在建新项目的时候已经明确了只用中间件A那么其他的中间件对我们来说可能就没有太大的存在意义很多时候不会想让这些多余的文件出现在代码中有没有办法来控制呢答案是肯定的可以把不需要的文件排除掉就可以了。文件过滤模板项目中有一个RequestLogMiddleware就用它来做例子。我们只需要做下面几件事就可以了。第一步在template.json中添加过滤加入一个名字为EnableRequestLog的symbol。同时指定源文件{ author: Catcher Wong,//others... symbols:{//是否启用RequestLog这个Middleware EnableRequestLog: { type: parameter, //它是参数 dataType:bool, //bool类型的参数 defaultValue: false //默认是不启用}}, sources: [{ modifiers: [{ condition: (!EnableRequestLog), //条件由EnableRequestLog参数决定 exclude: [ //排除下面的文件 src/TplDemo/Middlewares/RequestLogMiddleware.cs, src/TplDemo/Middlewares/RequestLogServiceCollectionExtensions.cs ]}]}] }第二步在模板的代码中做一下处理主要是Startup.cs因为Middleware就是在这里启用的。 using System; //other using...using TplDemo.Core;#if (EnableRequestLog) using TplDemo.Middlewares;#endif/// summary/// /// /summarypublic class Startup{ public void Configure(IApplicationBuilder app, IHostingEnvironment env) { //other code....#if (EnableRequestLog)//request Logapp.UseRequestLog();#endif app.UseMvc(routes {routes.MapRoute(name: default,template: {controllerHome}/{actionIndex}/{id?});});}}这样的话只要EnableRequestLog是true那么就可以包含这两段代码了。下面更新一下已经安装的模板。这个时候再去看它的帮助信息已经可以看到我们加的参数了。下面先建一个默认的(不启用RequestLog)dotnet new tpl -n NoLog这个命令等价于dotnet new tpl -n WithLog -E false下面是建好之后的目录结构和Startup.cs可以看到RequestLog相关的东西都已经不见了。再建一个启用RequestLog的看看是不是真的起作用了。dotnet new tpl -n WithLog -E true可以看到效果已经出来了。下面在介绍一个比较有用的特性。动态切换这个其实和上面介绍的内容相似。动态切换直接举个例子来说明吧。假设我们的模板支持MSSQL, MySQL, PgSQL和SQLite四种数据库操作在新建一个项目的时候只需要其中一种好比说要建一个PgSQL的肯定就不想看到其他三种。这里不想看到有两个地方一个是nuget包的引用一个是代码。上一小节是对某个具体的功能进行了开关的操作这里有了4个我们要怎么处理呢我们可以用类型是choice的参数来完成这个操作。修改template.json加入下面的内容{ author: Catcher Wong,//others symbols:{ sqlType: { type: parameter, datatype: choice, choices: [{ choice: MsSQL, description: MS SQL Server},{ choice: MySQL, description: MySQL},{ choice: PgSQL, description: PostgreSQL},{ choice: SQLite, description: SQLite}], defaultValue: MsSQL, description: The type of SQL to use}, MsSQL: { type: computed, value: (sqlType \MsSQL\)}, MySQL: { type: computed, value: (sqlType \MySQL\)}, PgSQL: { type: computed, value: (sqlType \PgSQL\)}, SQLite: { type: computed, value: (sqlType \SQLite\)}}
}看了上面的JSON内容之后相信大家也知道个所以然了。有一个名为sqlType的参数它有几中数据库选择默认是MsSQL。还另外定义了几个计算型的参数它的取值是和sqlType的值息息相关的。MsSQL,MySQL,PgSQL和SQLite这4个参数也是我们在代码里要用到的修改csproj文件让它可以根据sqlType来动态引用nuget包我们加入下面的内容ItemGroup Condition$(MySQL) True PackageReference IncludeMySqlConnector Version0.47.1 //ItemGroupItemGroup Condition$(PgSQL) True PackageReference IncludeNpgsql Version4.0.3 //ItemGroupItemGroup Condition$(SQLite) True PackageReference IncludeMicrosoft.Data.Sqlite Version2.1.0 //ItemGroup同样的代码也要做相应的处理#if (MsSQL)using System.Data.SqlClient;#elif (MySQL)using MySql.Data.MySqlClient;#elif (PgSQL)using Npgsql;#else using Microsoft.Data.Sqlite;#endifprotected DbConnection GetDbConnection() {#if (MsSQL) return new SqlConnection(_connStr);#elif (MySQL) return new MySqlConnection(_connStr);#elif (PgSQL) return new NpgsqlConnection(_connStr);#else return new SqliteConnection(_connStr);#endif }修改好之后同样要去重新安装这个模板安装好之后就可以看到sqlType这个参数了。下面分别创建一个MsSQL和PgSQL的项目用来对比和验证。先后执行dotnet new tpl -n MsSQLTest -s MsSQL
dotnet new tpl -n PgSQLTest -s PgSQL然后打开对应的csproj可以看到PgSQL的添加多了NPgsql这个包。而MsSQL的却没有。同样的DapperRepositoryBase也是一样的效果。在创建Connection对象的时候都根据模板来生成了。当然这个是在我们自己本地安装的模板其他人是没有办法使用的。如果想公开可以发布到nuget上面去。如果是在公司内部共享可以搭建一个内部的nuget服务将模板上传到内部服务器里面去。下面是一些可以开箱即用的模板https://dotnetnew.azurewebsites.net/总结有一个自己的项目模板(脚手架)还是很方便的。一建生成自己需要的东西减少了不必要的代码复制可以将更多精力放在业务实现上。在平时还是要有一些积累当积累足够丰富之后我们的脚手架可能就会变得十分强大。参考文档dotnet new下面默认的模板 https://github.com/aspnet/Templatingtemplating的源码 https://github.com/dotnet/templatingtemplate.json的说明 https://github.com/dotnet/templating/wiki/Reference-for-template.jsondotnet cli的文档 https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet?tabsnetcore21最后是文中的示例代码 https://github.com/catcherwong/Demos/tree/master/src/Template 原文地址:https://www.cnblogs.com/catcher1994/p/10061470.html.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com