1. 模板項(xiàng)目一覽
如果創(chuàng)建ASP.NET Core Web Application,目前官方預(yù)置了7種模板項(xiàng)目供我們選擇胆绊。從中我們可以看出氨鹏,既有我們熟悉的MVC、WebAPI压状,又新添加了Razor Page仆抵,以及結(jié)合比較流行的Angular、React前端框架的模板項(xiàng)目种冬×统螅基于給出的模板,我們可以根據(jù)自己的需求選擇合適的模板搭建項(xiàng)目框架著手開(kāi)發(fā)娱两。同時(shí)莺匠,我們也可以基于提供的結(jié)合Angular、React客戶端的模板項(xiàng)目來(lái)實(shí)施前后端分離的開(kāi)發(fā)策略十兢。
2. Empty 模板項(xiàng)目
我們先來(lái)看看創(chuàng)建的Empty模板項(xiàng)目結(jié)構(gòu):
從圖中可以得知主要由以下幾個(gè)部分組成:
- Dependencies:組織項(xiàng)目的依賴關(guān)系趣竣。從圖中我們可以看到依賴被細(xì)化為三個(gè)類別:Analyzers、NuGet旱物、SDK遥缕。其中NuGet是專門為.net設(shè)計(jì)的包管理器,組織從NuGet上安裝的依賴項(xiàng)宵呛;SDK主要是Microsoft底層的系列依賴单匣;其實(shí)還有另外幾個(gè)類別:Projects、Bower、npm户秤。Projects就是直接的項(xiàng)目依賴码秉;Bower是專門為web設(shè)計(jì)的包管理器,用來(lái)組織web前端依賴虎忌;npm是專門為javascript設(shè)計(jì)的包管理器泡徙,用來(lái)組織javascript的相關(guān)依賴。
- Properties:其中僅包含launchSettings.json文件膜蠢,該文件用于指定應(yīng)用程序的啟動(dòng)設(shè)置堪藐。
- wwwroot:根目錄,一般用來(lái)定義靜態(tài)文件挑围,如js礁竞、css、html杉辙、img模捂、ico等等。
- Program:程序入口蜘矢,其中定義了Main函數(shù)作為入口函數(shù)狂男。從這一點(diǎn)可以看出,其實(shí)質(zhì)是控制臺(tái)應(yīng)用品腹。
- Startup:程序啟動(dòng)類岖食。
2.1. 啟動(dòng)設(shè)置之launchSettings.json
首先該json文件中配置的屬性可以參考launchSettings.json。
2.2. 入口函數(shù)之Main函數(shù)
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
ASP.NET Core應(yīng)用程序需要由Host(宿主)進(jìn)行管理舞吭,宿主為其提供運(yùn)行環(huán)境并負(fù)責(zé)啟動(dòng)泡垃。所以Main函數(shù)主要是用來(lái)初始化宿主環(huán)境,而宿主環(huán)境的初始化需要借助WebHostBuilder羡鸥。初始化完畢后蔑穴,調(diào)用Run()方法來(lái)啟動(dòng)應(yīng)用程序。
- WebHost.CreaateDefaultBuilder():創(chuàng)建WebHostBuilder惧浴。
- UseStartup<Startup>():指定啟動(dòng)類存和,用于依賴注入和中間件注冊(cè)。
- Build():返回初始化完畢的IWebHost宿主衷旅。
- Run():?jiǎn)?dòng)WebHost哑姚。
2.3. 宿主構(gòu)造器之WebHostBuilder
以上Program的簡(jiǎn)單幾行代碼,完成了一個(gè)應(yīng)用程序的配置和啟動(dòng)芜茵。但簡(jiǎn)潔的代碼不見(jiàn)得簡(jiǎn)單叙量。我們結(jié)合源碼來(lái)看一看。
public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
var builder = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
if (env.IsDevelopment())
{
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly, optional: true);
}
}
config.AddEnvironmentVariables();
if (args != null)
{
config.AddCommandLine(args);
}
})
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
})
.UseIISIntegration()
.UseDefaultServiceProvider((context, options) =>
{
options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
});
return builder;
}
主要包含以下幾個(gè)部分:
- UseKestrel:使用Kestrel作為Web server九串。
- UseContentRoot:指定Web host使用的content root(內(nèi)容根目錄)绞佩,比如Views寺鸥。默認(rèn)為當(dāng)前應(yīng)用程序根目錄。
- ConfigureAppConfiguration:設(shè)置當(dāng)前應(yīng)用程序配置品山。主要是讀取 appsettinggs.json 配置文件胆建、開(kāi)發(fā)環(huán)境中配置的UserSecrets、添加環(huán)境變量和命令行參數(shù) 肘交。
- ConfigureLogging:讀取配置文件中的Logging節(jié)點(diǎn)笆载,配置日志系統(tǒng)。
- UseIISIntegration:使用IISIntegration 中間件涯呻。
- UseDefaultServiceProvider:設(shè)置默認(rèn)的依賴注入容器凉驻。
2.4. 啟動(dòng)類之Startup
public class Startup
{
// This method gets called by the runtime.
//Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
}
// This method gets called by the runtime.
//Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
}
該類主要包括兩個(gè)方法:
- ConfigureService:用于依賴服務(wù)注冊(cè)。
- Configure:用于指定應(yīng)用程序?qū)⑷绾雾憫?yīng)每一個(gè) HTTP 請(qǐng)求复罐。一般用于注冊(cè)中間件涝登。
其中涉及到下以下幾個(gè)可用服務(wù):
- IServiceCollection:當(dāng)前容器中各服務(wù)的配置集合,ASP.NET Core內(nèi)置的依賴注入容器效诅。
- IApplicationBuilder:用于構(gòu)建應(yīng)用程序的請(qǐng)求管道胀滚。
- IHostingEnvironment :提供了當(dāng)前的 EnvironmentName、WebRootPath 以及 ContentRoot等乱投。
2.5. 啟動(dòng)流程
首先我們需要明白咽笼,我們創(chuàng)建的.net core web application其實(shí)質(zhì)是一個(gè)獨(dú)立的控制臺(tái)應(yīng)用程序,不能直接處理Http請(qǐng)求戚炫,需要借助Web Server向外提供服務(wù)剑刑。.net core中默認(rèn)使用內(nèi)置的支持跨平臺(tái)的Kestrel作為web server(當(dāng)然還有其他web server可供選擇,比如WebListener嘹悼、Http.sys等等)叛甫。Web server是需要宿主環(huán)境來(lái)承載它层宫。比如:Windows 上的IIS杨伙、Windows Services,Linux上的Apache萌腿、Nginx限匣,或者Docker都可以作為Web Server的宿主。
而宿主就是用來(lái)負(fù)責(zé)啟動(dòng)我們的.net core 應(yīng)用程序的毁菱。比如:IIS新增了一個(gè) AspNetCoreModule 模塊米死,它負(fù)責(zé) ASP.NET Core 程序的啟動(dòng)與停止,并能監(jiān)聽(tīng) ASP.NET Core 程序的狀態(tài)贮庞,在我們的應(yīng)用程序意外崩潰時(shí)重新啟動(dòng)峦筒。
當(dāng)僅僅是在內(nèi)網(wǎng)中暴露服務(wù)的話,可以直接使用Kestrel處理http請(qǐng)求窗慎。否則物喷,還是借助反向代理服務(wù)器(IIS卤材、Nginx、Apache等)來(lái)轉(zhuǎn)發(fā)http請(qǐng)求峦失。但一般我們建議結(jié)合使用反向代理服務(wù)器來(lái)處理http請(qǐng)求扇丛,因?yàn)榉聪虼矸?wù)器可以在Kestrel之前做一些額外的處理(了解更多,可參考Introduction to Kestrel web server implementation in ASP.NET Core)尉辑。
通過(guò)以上的描述我們引入了Host與Server的概念帆精。我們可以簡(jiǎn)單理解為host是一個(gè)進(jìn)程用來(lái)管理應(yīng)用程序,而server是用來(lái)暴露應(yīng)用程序服務(wù)的隧魄。也可以理解為host是對(duì)server的一層包裝卓练。
3. MVC vs Razor Page
ASP.NET MVC 是一套基于Microsoft .NET Framework的用來(lái)開(kāi)發(fā)web應(yīng)用程序的開(kāi)源框架。其基于關(guān)注點(diǎn)分離的思想將應(yīng)用程序主要分為三個(gè)部分:Model堤器、View昆庇、Controller。在ASP.NET Core中同樣延續(xù)了MVC的優(yōu)良設(shè)計(jì)闸溃。
在ASP.NET MVC中Razor作為一個(gè)高級(jí)視圖引擎存在整吆,Razor提供了一種新的標(biāo)記語(yǔ)義,其大大減少了用戶輸入且具有表現(xiàn)力辉川,主要的特點(diǎn)是使用@符號(hào)去書(shū)寫(xiě)標(biāo)記表蝙。
而在ASP.NET Core中Razor不僅僅是一種視圖引擎,其提供了一種新的頁(yè)面設(shè)計(jì)方式——Razor Page乓旗。其主要的特點(diǎn)在于:
- 基于文件路徑的路由系統(tǒng)府蛇;
- Razor Page類似于WebForm,一種MVVM的架構(gòu)屿愚,支持雙向綁定汇跨;
- Razor Page符合單一職責(zé)原則,每個(gè)頁(yè)面獨(dú)立存在妆距,視圖和代碼緊密組織在一起穷遂。
4. MVC vs WebAPI
本質(zhì)上的區(qū)別在于:ASP.NET MVC 用來(lái)創(chuàng)建web應(yīng)用返回視圖和數(shù)據(jù);但是ASP.NET WEB API 是用來(lái)創(chuàng)建完整的HTTP服務(wù)娱据,僅返回?cái)?shù)據(jù)無(wú)視圖返回蚪黑。
就項(xiàng)目結(jié)構(gòu)而言,差別如下:
5. Angualr 模板項(xiàng)目
我們可以借助Angular來(lái)開(kāi)發(fā)SPA web應(yīng)用中剩,其結(jié)構(gòu)就與MVC相比忌穿,主要多了ClientApp文件夾。其代碼結(jié)構(gòu)如下圖所示:
6. 最后
關(guān)于模板項(xiàng)目的介紹就簡(jiǎn)要介紹到這里结啼,我們后續(xù)在結(jié)合實(shí)際運(yùn)用繼續(xù)深入探討掠剑!