<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          打造自己的.NET Core項目模板

          共 6885字,需瀏覽 14分鐘

           ·

          2021-01-13 22:06

          1.前言

          每個人都有自己習(xí)慣的項目結(jié)構(gòu),有人的喜歡在項目里面建解決方案文件夾;有的人喜歡傳統(tǒng)的三層命名;有的人喜歡單一,簡單的項目一個csproj就搞定。。

          反正就是蘿卜青菜,各有所愛。

          可能不同的公司對這些會有特定的要求,也可能會隨開發(fā)自己的想法去實踐。

          那么,問題就來了。如果有一個新項目,你會怎么去創(chuàng)建?

          可能比較多的方式會是下面三種:

          • 簡單粗暴型,打開VS就是右鍵添加,然后引入一堆包,每個項目添加引用。
          • 腳本型,基于dotnet cli,創(chuàng)建解決方案,創(chuàng)建項目,添加包,添加項目引用。
          • 高大上型,VS項目模板,直接集成到VS上面了。以前我也是基于dotnet cli寫好了sh或ps的腳本,然后用這些腳本來生成新項目。

          但是呢,這三種方式,始終都有不盡人意的地方。

          因為建好的都是空模板,還要做一堆復(fù)雜的操作才可以讓項目“正常”的跑起來。比如,這個公共類要抄過來,那個公共類要抄過來。。。這不是明擺著浪費時間嘛。。。

          下面介紹一個小辦法來幫大家省點時間。

          基于dotnet cli創(chuàng)建自己的項目模板,也就是大家常說的腳手架。

          2.dotnet cli項目模板預(yù)熱

          開始正題之前,我們先看一下dotnet cli自帶的一些模板。

          可以看到種類還是很多的,由于工作大部分時間都是在寫WebAPI,所以這里就用WebAPI來寫個簡單的模板。

          下面我們就基于dotnet cli寫一個自己的模板。

          3.編寫自己的模板

          既然是模板,就肯定會有一個樣例項目。

          下面我們建一個樣例項目,大致成這樣,大家完全可以按照自己習(xí)慣來。

          這其實就是一個普通的項目,里面添加了NLog,Swagger,Dapper等組件,各個項目的引用關(guān)系是建好的。

          該有的公共類,里面也都包含了,好比宇內(nèi)分享的那個WebHostBuilderJexusExtensions。

          下面是這個模板跑起來的效果。

          就是一個簡單的Swagger頁面。

          現(xiàn)在樣例已經(jīng)有了,要怎么把這個樣例變成一個模板呢?

          答案就是template.json

          在樣例的根目錄創(chuàng)建一個文件夾.template.config,同時在這個文件夾下面創(chuàng)建template.json。

          示例如下:

          {
          ????"author":?"Catcher?Wong",?//必須
          ????"classifications":?[?"Web/WebAPI"?],?//必須,這個對應(yīng)模板的Tags
          ????"name":?"TplDemo",?//必須,這個對應(yīng)模板的Templates
          ????"identity":?"TplDemoTemplate",?//可選,模板的唯一名稱
          ????"shortName":?"tpl",?//必須,這個對應(yīng)模板的Short?Name
          ????"tags":?{
          ??????"language":?"C#"?,
          ??????"type":"project"
          ????},
          ????"sourceName":?"TplDemo",??//?可選,要替換的名字
          ????"preferNameDirectory":?true??//?可選,添加目錄??
          }

          在這里,有幾個比較重要的東西,一個是shortName,一個是sourceName。

          • shortName,簡寫,偷懶必備,好比能寫 -h 就絕對不寫 ``--help`
          • sourceName,這是個可選的字段,它的值會替換指定的項目名,正常是把項目名賦值在這里。如果不指定,創(chuàng)建的項目就和樣例項目保持一致。在寫完template.json之后,還需要安裝一下這個模板到我們的cli中。

          使用 dotnet new -i進(jìn)行模板的安裝。

          下面是安裝示例:

          dotnet?new?-i?./content/TplDemo

          這里要注意的是,與.template.config文件夾同級的目錄,都會被打包進(jìn)模板中。在執(zhí)行安裝命令之后,就可以看到我們的模板已經(jīng)安裝好了。

          這個時候已經(jīng)迫不及待的想來試試這個模板了。

          先來看看這個模板的幫助信息。

          dotnet?new?tpl?-h

          因為我們目前還沒有設(shè)置參數(shù),所以這里顯示的是還沒有參數(shù)。

          下面來創(chuàng)建一個項目試試。

          從創(chuàng)建一個項目,到運行起來,很簡單,效果也是我們預(yù)期的。

          下面來看看,新建的這個HelloTpl這個項目的目錄結(jié)構(gòu)和我們的模板是否一樣。

          可以看到,除了名字,其他的內(nèi)容都是一樣的。

          是不是感覺又可以少復(fù)制粘貼好多代碼了。

          雖說,現(xiàn)在建項目,已經(jīng)能把一個大的模板完整的copy出來了,但是始終不是很靈活!

          可能有小伙伴會問,明明已經(jīng)很方便了呀,為什么還會說它不靈活呢?

          且聽我慢慢道來。

          如果說這個模板是個大而全的模板,包含了中間件A,中間件B,中間件C等N個中間件!

          而在建新項目的時候,已經(jīng)明確了只用中間件A,那么其他的中間件對我們來說,可能就沒有太大的存在意義!

          很多時候,不會想讓這些多余的文件出現(xiàn)在代碼中,有沒有辦法來控制呢?

          答案是肯定的!可以把不需要的文件排除掉就可以了。

          4.文件過濾

          模板項目中有一個RequestLogMiddleware,就用它來做例子。

          我們只需要做下面幾件事就可以了。

          第一步,在template.json中添加過濾

          加入一個名字為EnableRequestLogsymbol。同時指定源文件

          {
          ????"author":?"Catcher?Wong",
          ????//others...
          ????"symbols":{
          ??????//是否啟用RequestLog這個Middleware
          ??????"EnableRequestLog":?{
          ????????"type":?"parameter",?//它是參數(shù)
          ????????"dataType":"bool",?//bool類型的參數(shù)
          ????????"defaultValue":?"false"?//默認(rèn)是不啟用
          ??????}
          ????},
          ????"sources":?[
          ??????{
          ??????????"modifiers":?[
          ??????????????{
          ??????????????????"condition":?"(!EnableRequestLog)",?//條件,由EnableRequestLog參數(shù)決定
          ??????????????????"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

          ????///?
          ????///?
          ????///?

          ????public?class?Startup
          ????{
          ????????public?void?Configure(IApplicationBuilder?app,?IHostingEnvironment?env)
          ????????{
          ????????????//other?code....
          #if?(EnableRequestLog)
          ????????????//request?Log
          ????????????app.UseRequestLog();
          #endif????????????
          ????????????app.UseMvc(routes?=>
          ????????????{
          ????????????????routes.MapRoute(
          ????????????????????name:?"default",
          ????????????????????template:?"{controller=Home}/{action=Index}/{id?}");
          ????????????});
          ????????}
          ????}

          這樣的話,只要EnableRequestLog是true,那么就可以包含這兩段代碼了。

          下面更新一下已經(jīng)安裝的模板。

          這個時候再去看它的幫助信息,已經(jīng)可以看到我們加的參數(shù)了。

          下面先建一個默認(rèn)的(不啟用RequestLog)

          dotnet?new?tpl?-n?NoLog

          這個命令等價于

          dotnet?new?tpl?-n?WithLog?-E?false

          下面是建好之后的目錄結(jié)構(gòu)和Startup.cs

          可以看到RequestLog相關(guān)的東西都已經(jīng)不見了。

          再建一個啟用RequestLog的,看看是不是真的起作用了。

          dotnet?new?tpl?-n?WithLog?-E?true

          可以看到,效果已經(jīng)出來了。

          下面在介紹一個比較有用的特性。動態(tài)切換,這個其實和上面介紹的內(nèi)容相似。

          5.動態(tài)切換

          直接舉個例子來說明吧。

          假設(shè)我們的模板支持MSSQL, MySQL, PgSQL和SQLite四種數(shù)據(jù)庫操作

          在新建一個項目的時候,只需要其中一種,好比說要建一個PgSQL的,肯定就不想看到其他三種。

          這里不想看到,有兩個地方,一個是nuget包的引用,一個是代碼。

          上一小節(jié)是對某個具體的功能進(jìn)行了開關(guān)的操作,這里有了4個,我們要怎么處理呢?

          我們可以用類型是choice的參數(shù)來完成這個操作。

          修改template.json,加入下面的內(nèi)容

          {
          ??"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內(nèi)容之后,相信大家也知道個所以然了。有一個名為sqlType的參數(shù),它有幾中數(shù)據(jù)庫選擇,默認(rèn)是MsSQL。

          還另外定義了幾個計算型的參數(shù),它的取值是和sqlType的值息息相關(guān)的。

          MsSQL,MySQL,PgSQL和SQLite這4個參數(shù)也是我們在代碼里要用到的!!

          修改csproj文件,讓它可以根據(jù)sqlType來動態(tài)引用nuget包,我們加入下面的內(nèi)容

          "'$(MySQL)'?==?'True'?">??
          ????"MySqlConnector"?Version="0.47.1"?/>


          "'$(PgSQL)'?==?'True'?">??
          ????"Npgsql"?Version="4.0.3"?/>


          "'$(SQLite)'?==?'True'?">??
          ????"Microsoft.Data.Sqlite"?Version="2.1.0"?/>

          同樣的,代碼也要做相應(yīng)的處理

          #if?(MsSQL)
          ????using?System.Data.SqlClient;
          #elif?(MySQL)
          ????using?MySql.Data.MySqlClient;
          #elif?(PgSQL)
          ????using?Npgsql;
          #else?
          ????using?Microsoft.Data.Sqlite;
          #endif

          ????protected?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這個參數(shù)了。

          下面分別創(chuàng)建一個MsSQL和PgSQL的項目,用來對比和驗證。

          先后執(zhí)行

          dotnet?new?tpl?-n?MsSQLTest?-s?MsSQL?
          dotnet?new?tpl?-n?PgSQLTest?-s?PgSQL

          然后打開對應(yīng)的csproj

          可以看到,PgSQL的,添加多了NPgsql這個包。而MsSQL的卻沒有。

          同樣的,DapperRepositoryBase也是一樣的效果。在創(chuàng)建Connection對象的時候,都根據(jù)模板來生成了。

          當(dāng)然這個是在我們自己本地安裝的模板,其他人是沒有辦法使用的。

          如果想公開,可以發(fā)布到nuget上面去。如果是在公司內(nèi)部共享,可以搭建一個內(nèi)部的nuget服務(wù),將模板上傳到內(nèi)部服務(wù)器里面去。

          下面是一些可以開箱即用的模板:

          https://dotnetnew.azurewebsites.net/

          6. 總結(jié)

          有一個自己的項目模板(腳手架),還是很方便的。

          一建生成自己需要的東西,減少了不必要的代碼復(fù)制,可以將更多精力放在業(yè)務(wù)實現(xiàn)上。

          在平時還是要有一些積累,當(dāng)積累足夠豐富之后,我們的腳手架可能就會變得十分強(qiáng)大。

          參考文檔:

          dotnet new下面默認(rèn)的模板 https://github.com/aspnet/Templating

          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?tabs=netcore21

          最后是文中的示例代碼:https://github.com/catcherwong/Demos/tree/master/src/Template

          原文:https://www.cnblogs.com/catcher1994/p/10061470.html







          回復(fù)?【關(guān)閉】學(xué)關(guān)
          回復(fù)?【實戰(zhàn)】獲取20套實戰(zhàn)源碼
          回復(fù)?【被刪】學(xué)
          回復(fù)?【訪客】學(xué)
          回復(fù)?【小程序】學(xué)獲取15套【入門+實戰(zhàn)+賺錢】小程序源碼
          回復(fù)?【python】學(xué)微獲取全套0基礎(chǔ)Python知識手冊
          回復(fù)?【2019】獲取2019 .NET 開發(fā)者峰會資料PPT
          回復(fù)?【加群】加入dotnet微信交流群

          副業(yè)剛需,沒有人能拒絕這個網(wǎng)站!


          終于GitHub App 已支持簡體中文!




          瀏覽 33
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲 偷拍 在线 无码 制服 另类 | 国产传媒午夜成人 | 欧美抄逼视频播放 | 亚洲88| 欧美日韩毛 |