深入浅出Dotnet Core的项目结构变化
有時候,越是基礎(chǔ)的東西,越是有人不明白。
?
前幾天Review一個項目的代碼,發(fā)現(xiàn)非常基礎(chǔ)的內(nèi)容,也會有人理解出錯。
今天,就著這個點,寫一下Dotnet Core的主要類型的項目結(jié)構(gòu),以及之間的轉(zhuǎn)換和演化。
一、最基礎(chǔ)的應(yīng)用Console
控制臺應(yīng)用,是Dotnet Core乃至前邊的Dotnet Framework中,最基礎(chǔ)的項目。
我們來創(chuàng)建一個Console項目看一下:
%?dotnet?new?console?-o?demo創(chuàng)建完成后,打開工程。工程里只有一個文件Program.cs,里面只有一個方法Main:
namespace?demo {class?Program{static?void?Main(string[]?args){Console.WriteLine("Hello?World!");}} }在Dotnet Core所有類型的項目中,Program.cs都是最開始的入口,main方法,也是最開始的入口方法。
?
這個工程中,還有一個文件也需要了解一下,demo.csproj,這是這個項目的定義文件:
<Project?Sdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>Exe</OutputType><TargetFramework>net5.0</TargetFramework></PropertyGroup></Project>這里面,OutputType告訴編輯器這個工程編譯后可以直接執(zhí)行,TargetFramework定義運行的框架。
注意,這個框架字串有個對照表:net5.0對應(yīng)的是.Net 5.0;如果你想用Dotnet Core 3.1,對應(yīng)的字符串是netcoreapp3.1,而不是net3.1。準(zhǔn)確的說,3.1是.Net Core 3.1,而5.0是.Net 5.0。不用太糾結(jié),微軟的命名規(guī)則而已。
?
這就是控制臺應(yīng)用Console的初始狀態(tài)。
下面,我們看看這個工程如何轉(zhuǎn)變?yōu)閃eb應(yīng)用。
二、轉(zhuǎn)為Web應(yīng)用
第一件事,我們需要改動demo.csproj項目定義文件。
Web應(yīng)用跑在WebHost上面,而不是從直接執(zhí)行。所以,我們需要把OutputType項去掉。
另外,SDK也需要改一下。Console我們用的是Microsoft.NET.Sdk,Web應(yīng)用要改成Microsoft.NET.Sdk.Web:
<Project?Sdk="Microsoft.NET.Sdk.Web"><PropertyGroup><TargetFramework>net5.0</TargetFramework></PropertyGroup></Project>改完保存。
這時候,應(yīng)該可以注意到,項目的發(fā)生了變化:
依賴的框架從Microsoft.NETCore.App變成了兩個,多了一個Microsoft.AspNetCore.App,表明現(xiàn)在這是一個Asp.net Core的應(yīng)用;
項目中自動生成了一個目錄Properties,下面多了一個文件launchSettings.json。這個文件大家應(yīng)該很熟悉,就不解釋了。
這時候,應(yīng)用已經(jīng)從Console轉(zhuǎn)為了Web應(yīng)用。
?
Asp.Net Core框架提供了Host供Web加載。我們需要做的,是把Host構(gòu)建器加到程序中。通常,我們需要兩個構(gòu)建器:
通用主機 Generic host builder
Web主機 Web host builder?
?
1. 配置通用主機
通用主機在Microsoft.Extensions.Hosting.Host中,主要給Web應(yīng)用提供以下功能:
依賴注入
日志
配置 IConfiguration
IHostedService實現(xiàn)
加入通用主機很簡單,就一個方法CreateDefaultBuilder:
class?Program {static?void?Main(string[]?args){Host.CreateDefaultBuilder(args).Build().Run();} }2. 配置Web主機
Web主機才是真正與Web相關(guān)的內(nèi)容,主要實現(xiàn):
Http支持
設(shè)置Kestrol服務(wù)器為Web服務(wù)器
添加IIS支持
加入Web主機,也是一個方法ConfigureWebHostDefaults:
class?Program {static?void?Main(string[]?args){Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder?=>{}).Build().Run();} }這個方法用來添加Http請求管道并注入我們需要的服務(wù)。而注入我們需要的服務(wù),就是我們最常見的Startup.cs的內(nèi)容。
?
下面,我們先創(chuàng)建Startup.cs,
namespace?demo {public?class?Startup{} }在前邊ConfigureWebHostDefaults中,加入Startup,并補齊代碼:
class?Program {static?void?Main(string[]?args){Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder?=>{webBuilder.UseStartup<Startup>();}).Build().Run();} }?
這就是Program.cs中的完整代碼了。整理一下,就是我們常見的樣子:
public?class?Program {public?static?void?Main(string[]?args){CreateHostBuilder(args).Build().Run();}public?static?IHostBuilder?CreateHostBuilder(string[]?args)?=>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder?=>{webBuilder.UseStartup<Startup>();}); }不過,到這兒還不能正常運行,因為Startup.cs現(xiàn)在還是空的。
3. 補齊Startup類
Startup類在Asp.net Core應(yīng)用中有著重要的作用。這個類用于:
使用DI容器注入服務(wù)
設(shè)置Http Request管道以插入中間件
?
下面我們補齊所需的方法:
namespace?demo {public?class?Startup{public?void?ConfigureServices(IServiceCollection?services){}public?void?Configure(IApplicationBuilder?app,?IWebHostEnvironment?env){}} }運行,到這兒,Web應(yīng)用已經(jīng)可以正常啟動了。
4. 給應(yīng)用添加路由
Web應(yīng)用啟動了,但里面什么也沒有,是空的。
要訪問Web應(yīng)用中的任何資源,需要配置路由。這兒的路由,基本上就是傳入Http請求與資源之間的映射。
我們可以用下面的中間件來啟動路由:
UseRouting
UseEndpoints
加一下試試:
public?void?Configure(IApplicationBuilder?app,?IWebHostEnvironment?env) {app.UseRouting();app.UseEndpoints(endpoint?=>?{endpoint.MapGet("/",?async?context?=>{await?context.Response.WriteAsync("Hello?from?Demo");});}); }這次運行,瀏覽器中就看到正確的輸出了。
我們可以用MapGet映射更多資源:
public?void?Configure(IApplicationBuilder?app,?IWebHostEnvironment?env) {app.UseRouting();app.UseEndpoints(endpoint?=>{endpoint.MapGet("/",?async?context?=>{await?context.Response.WriteAsync("Hello?from?Demo");});endpoint.MapGet("/test",?async?context?=>{await?context.Response.WriteAsync("Hello?from?Demo.Test");});endpoint.MapGet("/about",?async?context?=>{await?context.Response.WriteAsync("Hello?from?Demo.About");});}); }?
到這兒,我們成功地把Console應(yīng)用轉(zhuǎn)為了Web應(yīng)用。
三、延伸內(nèi)容
上面完成的Web應(yīng)用,算是Web應(yīng)用中的基礎(chǔ)。基于這個內(nèi)容,我們還可以擴展到別的項目結(jié)構(gòu)。
1. 改為MVC應(yīng)用
需要在ConfigureServices中注入AddControllersWithViews,并在Configure中添加MapDefaultControllerRoute:
public?class?Startup {public?void?ConfigureServices(IServiceCollection?services){services.AddControllersWithViews();}public?void?Configure(IApplicationBuilder?app,?IWebHostEnvironment?env){app.UseRouting();app.UseEndpoints(endpoint?=>{endpoint.MapDefaultControllerRoute();});} }2. 改為WebAPI應(yīng)用
需要注入AddControllers和MapControllers:
public?class?Startup {public?void?ConfigureServices(IServiceCollection?services){services.AddControllers();}public?void?Configure(IApplicationBuilder?app,?IWebHostEnvironment?env){app.UseRouting();app.UseEndpoints(endpoint?=>{endpoint.MapControllers();});} }3. 改為Razor應(yīng)用
需要注入AddRazorPages和MapRazorPages:
public?class?Startup {public?void?ConfigureServices(IServiceCollection?services){services.AddRazorPages();}public?void?Configure(IApplicationBuilder?app,?IWebHostEnvironment?env){app.UseRouting();app.UseEndpoints(endpoint?=>{endpoint.MapRazorPages();});} }四、總結(jié)
看下來,其實過程很簡單。通過這種方式,能更進一步理解Dotnet Core的項目結(jié)構(gòu)以及應(yīng)用的運行過程。
希望對大家能有所幫助。
?
本文的配套代碼在:https://github.com/humornif/Demo-Code/tree/master/0038/demo
喜歡就來個三連,讓更多人因你而受益
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的深入浅出Dotnet Core的项目结构变化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 推荐:Dapper扩展-Dapper.S
- 下一篇: 使用 C# 9 的records作为强类