.Net Core应用框架Util介绍(三)
上篇.Net Core應用框架Util介紹(二)介紹了Util的開發環境,并讓你把Demo運行起來。本文將介紹該Demo的前端Angular運行機制以及目錄結構。
?
目錄結構
?? 在VS上打開Util Demo,會看見如下的目錄結構。
現代前端通常采用VS Code開發,不過我們為了使用TagHelper,需要采用VS開發,這為你提供了更多的選擇。?
你可以將WebApi和Angular應用放在同一個項目中,就像現在看見的那樣。也可以分別把WebApi和Angular應用放到不同項目中。?
如果你已經習慣了VS Code開發,這同樣沒問題,不過你將放棄TagHelper帶來的強類型代碼提示和編譯時檢查特性。?
對于Angular,它提供了ng cli命令行工具,你可以用ng cli來創建項目結構。
前文已簡要介紹了TagHelper,它是用來提升Angular視圖頁面開發效率的利器。為了使用TagHelper,不得不放棄ng cli,因為它不支持在Angular組件上配置服務端動態地址。
下面介紹這個項目中包含的目錄和文件。
?
Apis目錄
這個目錄用來存放Web Api控制器。
ApplicationController演示了普通CRUD操作,RoleController演示了樹型層次的CRUD操作。
你暫時不要關心Web Api CRUD操作,我會在后續介紹。
?
?Areas目錄
? 用過Asp.Net Mvc的同學可能知道,Areas就是區域,它的作用是提供模塊化管理。我們把不同的模塊用Areas的區域分隔開,這樣在項目規模變大時,還能迅速找到相關頁面。
與傳統Asp.Net Mvc應用不同,Util的Areas控制器并不進行任何操作,只是簡單的返回視圖頁面,cshtml僅起到代碼生成器的作用。
一個更好的選擇是使用RazorPage,它把控制器和頁面合并了,將來會使用這種方式。?
Configs目錄
? 你并不需要它,我在Demo中用來放測試配置,項目上我通常把Configs目錄放在應用層類庫。
Controllers目錄
? Controllers目錄是用來放置與首頁相關的控制器。
Datas目錄
Util引入了DDD經典架構,Datas位于基礎設施層,一些人把它叫倉儲層。
Datas通常放在單獨的類庫,為了演示簡單,我放在該WEB項目的目錄中。
DbScripts目錄
這個目錄提供了Sql Server建庫腳本。
一些人可能很驚訝,什么年代了,還在使用Db First開發。
在多年的開發實戰中,我摸索到一套以PowerDesigner數據建模配合CodeSmith代碼生成的開發模式。對于CRUD,它具有快速高效的特點,同時你還能擁有清晰的數據字典以供未來查閱。
對于具備面向對象編程能力的人,這種方式并不會降低代碼質量和設計水平,在將代碼生成出來以后,通過手工調整就可達到與Code First相同的代碼水平。
我會在未來某個合適的時候介紹這種開發模式。
?Domains目錄
DDD經典架構中領域層相關的目錄,實際開發中將放到單獨的類庫。
Services目錄
DDD經典架構中應用層相關的目錄,實際開發中將放到單獨的類庫。
Typings目錄
? Angular相關的所有東西都在這里。
?
app目錄用來存放與業務相關的項目資源,比如Angular組件,指令,服務等。
值得注意的是,該目錄包含組件對應的.html文件,這些.html文件和.cshtml文件是怎樣的關系?
?
?
如果你從未運行過Util Demo項目,打開app目錄,并未找到任何.html文件。
你可能已經猜到了,.html文件是由.cshtml文件生成的。
你永遠都不應該手工編輯這些.html文件,因為在調試運行時將被覆蓋。?
test目錄包含Ts單元測試,我僅對極少數Helper進行單元測試。通過下面的npm命令把測試運行起來。
npm test?
util目錄包含對Angular常用API和Angular Material組件的封裝。
?
Angular組件由視圖和控制器兩部分構成。視圖即模板頁,包含html標簽??刂破饔脕砭帉戇壿?#xff0c;包含Ts代碼。換句話說,Angular應用開發主要是編寫html和ts(當然還有css,暫時不要管它)。
TagHelper并不是Util封裝Angular的唯一手段,對于Angular控制器,Util采用鏈式封裝手法,將Angular常用Api封裝得更加簡單易用,使你對Angular Api只要有一個模糊的印象就可以開發了。
對于Angular視圖頁面,并不能直接采用TagHelper簡單包裝,這樣會導致TagHelper過于復雜,另外很多功能需要在運行時進行判斷,TagHelper只在開發調試階段存在,所以采用兩層封裝會更加省力。
首先采用Angular組件或指令對Material組件進行封裝,然后采用TagHelper提供強類型提示。
對于希望采用VS Code開發的同學,Typings/util目錄中封裝的代碼同樣可以使用,它跟TagHelper沒有什么關系,你可以把它Copy到你的項目,我尚未把它發布到npm。?
Views目錄
Views目錄包含首頁。
appsettings.json文件
它是一個配置文件,數據庫連接字符串在這里。
nlog.config文件
它是NLog日志組件的配置文件,Util 采用NLog輸出開發調試和錯誤日志,默認位置是c:\log目錄。
package.json文件
它是npm包管理器的配置文件。
Program.cs文件
它是Asp.Net Core程序入口點文件。
Startup.cs文件
它是Asp.Net Core啟動文件,在這里配置依賴注入和中間件請求管道。
tsconfig.json文件
它是Typescript語言配置文件。
webpack.config.js文件
它是Webpack自動化構建工具的配置文件。
還有兩個配置文件隱藏在webpack.config.js下,它們對util和第三方Js框架進行處理。
?
運行機制
對于沒有前端基礎的同學,可能很難理解這個Demo是如何運行起來的,下面為你介紹這個Demo的運行機制,我們從npm包還原開始。?
?npm還原
當你輸入yarn和cnpm install node-sass,它會找到package.json文件的dependencies節,然后把需要的文件下載到node_modules目錄中。
?執行Webpack構建
然后輸入npm run dev,這里發生了什么?
npm run是npm的一個命令,它會查找package.json中scripts定義的命令。
?
npm run dev?
dev就是npm run要查找的命令名,它是一個約定俗成的名稱,代表開發階段配置,即develop,當然你不一定用這個名字,叫abc也可以。
npm run dev查找到package.json文件scripts節定義的dev命令,它的內容是npm run vendor && npm run app,這個命令是由兩個npm run命令組成的。
?npm run vendor
npm run vendor的內容是webpack --config webpack.config.vendor.js,這將對webpack.config.vendor.js執行構建操作。
webpack命令默認查找webpack.config.js文件,現在要查找的是webpack.config.vendor.js,所以需要添加參數—config。
我們來看看webpack.config.vendor.js包含什么內容。?
?webpack.config.vendor.js
vendorJs?對象用于配置將哪些第三方Js框架文件進行打包,vendorCss?對象用于配置需要打包的第三方框架提供的Css文件。?
entry屬性指定了需要打包的入口文件,output屬性則指定輸出的位置和文件名。?
當webpack.config.vendor.js執行完畢,會在Util.Samples.Webs項目的wwwroot目錄創建一個dist子目錄,并生成vendor.js和vendor.css兩個文件。
注意:vendor.js僅在開發調試階段使用,所以并沒有對它進行壓縮,正式發布并不需要執行vendorJs對象。
該腳本的最后一行證明了這一點。
return isDev ? [ vendorJs, vendorCss] : [vendorCss];?npm run app?
npm run app又包含兩個命令,用于執行webpack.config.util.js和webpack.config.js。
webpack --config webpack.config.util.js && webpack先來看看webpack.config.util.js。
?webpack.config.util.js
它將查找Util.Samples.Webs項目下Typings/util/index.ts文件,這是util默認導出文件,所有在外部需要訪問的類型都會從這里導出。
當webpack.config.util.js執行完畢,會在dist目錄創建util.js文件。
同樣的,util.js文件僅用于開發調試階段。?
下面看webpack.config.js。
?webpack.config.js
webpack.config.js查找Typings目錄下的main.ts,main.ts是angular項目的入口文件。
webpack通過遞歸依賴查找main.ts,將除了util.js和vendor.js以外所有引用到的ts或js文件打包到dist/app.js文件中。
注意,正式發布時,app.js將采用angular官方提供的webpack編譯插件@ngtools/webpack進行AOT編譯并打包生成。
?
現在dist目錄生成了如下文件。
0.chunk.js是由angular子模塊生成的js文件,當路由配置對子模塊啟用了延遲加載,每個子模塊都會生成一個獨立的js文件。
?
loadChildren以延遲加載的方式來配置SystemModule子模塊。
?運行機制
現在運行angular應用的js文件已經就緒,讓我們把它運行起來,在VS上F5啟動項目。?
注意:你應該使用Google?Chrome來打開它,IE瀏覽器,可以通過啟用polyfill來勉強支持,不過由于效果不佳,我已經把它扔掉了。?
當瀏覽器打開首頁http://localhost:5200,Asp.Net Core啟動文件Startup.cs中配置的默認路由將被激活,從而將請求發送到HomeController控制器的Index方法。
? Index方法直接返回了Views目錄下Index.cshtml首頁。
?
environment標簽是一個環境判斷條件,用于設置開發及上線等不同階段的內容。
<environment?include="Development">用于開發階段,<environment?exclude="Development">用于發布階段,可以看出,在發布后并不需要vendor.js和util.js文件,因為app.js會包含它們。?
好,現在瀏覽器加載了Index首頁,Angular應用是如何運行起來的呢?
Angular的引導過程
? 還記得Angular應用入口文件main.ts嗎,來看看它包含什么內容。
?
platformBrowserDynamic是為瀏覽器平臺提供的JIT動態編譯服務,它將引導AppModule根模塊的啟動。
AppModule是Angular應用的根模塊,它的主要任務之一就是啟動AppComponent根組件。
AppComponent是整個Angular應用的根組件,所有其它組件都將被加載到根組件中。
?
selector用于指定組件的自定義標簽,這里將根組件標簽定義為<app></app>,你發現它已經被放置在Index.cshtml中。?
AppComponent根組件準備啟動了,由于是JIT編譯,所以它需要獲取視圖。?
組件的視圖由templateUrl屬性指定。
templateUrl: env.prod() ? './app.component.html' : '/home/main'我們希望開發階段通過訪問服務端控制器來獲取視圖,這樣在編輯TagHelper時就能更方便,只需刷新頁面就能看見效果。?
env是一個環境檢測對象,prod方法如果返回true表明當前為正式環境,將從app.component.html靜態文件獲取視圖,如果是開發調試環境,則訪問服務端HomeController控制器的Main方法獲取視圖。?
Main方法上的Html特性,是用來幫助.cshtml生成.html靜態文件的輔助工具。?
一般情況下,你并不需要手工設置Html特性來生成html文件,Util提供了ViewControllerBase控制器基類,當你的視圖控制器繼承它,所有html文件就會生成到約定的目錄中。
?
由Template屬性設置的路徑可知,Typings/app中的項目結構也采用模塊化組織,與區域模塊相對應。
? 現在來看根組件的視圖。
? 這是你第一次看見Util封裝的TagHelper標簽,以<util-打頭的標簽都是Util TagHelper,它們以粗體顯示,這是由于安裝了Resharper的原因。
TagHelper在運行時會把html輸出到頁面,它們把弱類型的html封裝成了具有強類型提示的標簽。
如何知道某個TagHelper到底輸出了什么html呢?
一種辦法是打開它生成的.html文件來查找,不過當頁面很復雜時,這種辦法有點吃力。
另一種辦法是查看日志,Util TagHelper的每個組件都提供了write-log屬性,當設置為true,就會在C盤log目錄生成日志。
?
main.cshtml視圖中最關鍵的部分就是<router-outlet></router-outlet>標簽。
router-outlet是Angular路由的占位符,當根模塊AppModule中配置的路由激活時,相關的Angular組件就會被放進這個占位符中。
根模塊中的路由配置被拆分到一個單獨的模塊AppRoutingModule中,路由配置如下。
?
通過路由配置可以發現,當打開首頁時,命中路由第二項path:’’,會跳轉到/systems/application路徑,systems是一個子模塊,我們來查看它的路由配置。
?
?
/systems/application將激活ApplicationIndexComponent組件,并把它加載到根組件的<router-outlet></router-outlet>中。
ApplicationIndexComponent組件請求服務端地址/view/systems/application獲取視圖。
?
? /view打頭的地址將匹配到Areas區域控制器,這是在MVC路由配置中設置的。
?
控制器ApplicationController的Index方法將返回視圖。
?
Angular JIT編譯會在系統啟動時請求服務端URL,在Chrome瀏覽器F12調出開發者工具,刷新頁面,會觀察到頁面請求了Areas中的控制器。
所以你在開發階段運行項目會感覺比較慢,在正式發布后就沒這些開銷了。
小結
本文簡要介紹了Util Demo的目錄結構和運行機制,如果你沒有Angular基礎,估計還是很難看懂,建議你閱讀Angular中文網https://angular.cn。
未完待續,下一篇將對Util Demo的Angular封裝進行介紹,本來是準備這篇介紹的,不過限于篇幅,放到下篇,我知道,太長的文章既難寫更難讀。
寫文需要動力,請大家多多支持,點下推薦,Github點下星星。
Util應用框架交流一群: 24791014
相關文章:
.Net Core應用框架Util介紹(一)
.Net Core應用框架Util介紹(二)
原文地址:https://www.cnblogs.com/xiadao521/p/Util-Introduction-3.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的.Net Core应用框架Util介绍(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET Core中Object Poo
- 下一篇: Ocelot简易教程(三)之主要特性及路