深入浅出Dotnet Core的项目结构变化
source link: https://mp.weixin.qq.com/s?__biz=MjM5MjQwMDUzMw%3D%3D&%3Bmid=2247484211&%3Bidx=1&%3Bsn=7f45ac248b23c31e5088f64e98b70257
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
有时候,越是基础的东西,越是有人不明白。
前几天Review一个项目的代码,发现非常基础的内容,也会有人理解出错。
今天,就着这个点,写一下Dotnet Core的主要类型的项目结构,以及之间的转换和演化。
一、最基础的应用Console
控制台应用,是Dotnet Core乃至前边的Dotnet Framework中,最基础的项目。
我们来创建一个Console项目看一下:
% dotnet new console -o demo
创建完成后,打开工程。工程里只有一个文件 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
告诉编辑器这个工程编译后可以直接执行, TargetFramework
定义运行的框架。
注意,这个框架字串有个对照表: net5.0
对应的是 .Net 5.0
;如果你想用 Dotnet Core 3.1
,对应的字符串是 netcoreapp3.1
,而不是 net3.1
。准确的说,3.1是 .Net Core 3.1
,而5.0是 .Net 5.0
。不用太纠结,微软的命名规则而已。
这就是控制台应用Console的初始状态。
下面,我们看看这个工程如何转变为Web应用。
二、转为Web应用
第一件事,我们需要改动 demo.csproj
项目定义文件。
Web应用跑在 WebHost
上面,而不是从直接执行。所以,我们需要把 OutputType
项去掉。
另外,SDK也需要改一下。Console我们用的是 Microsoft.NET.Sdk
,Web应用要改成 Microsoft.NET.Sdk.Web
:
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net5.0</TargetFramework> </PropertyGroup> </Project>
改完保存。
这时候,应该可以注意到,项目的发生了变化:
-
依赖的框架从
Microsoft.NETCore.App
变成了两个,多了一个Microsoft.AspNetCore.App
,表明现在这是一个Asp.net Core
的应用; -
项目中自动生成了一个目录
Properties
,下面多了一个文件launchSettings.json
。这个文件大家应该很熟悉,就不解释了。
这时候,应用已经从Console转为了Web应用。
Asp.Net Core框架提供了Host供Web加载。我们需要做的,是把Host构建器加到程序中。通常,我们需要两个构建器:
-
通用主机 Generic host builder
-
Web主机 Web host builder
1. 配置通用主机
通用主机在 Microsoft.Extensions.Hosting.Host
中,主要给Web应用提供以下功能:
-
依赖注入
-
日志
-
配置 IConfiguration
-
IHostedService实现
加入通用主机很简单,就一个方法 CreateDefaultBuilder
:
class Program { static void Main(string[] args) { Host.CreateDefaultBuilder(args) .Build() .Run(); } }
2. 配置Web主机
Web主机才是真正与Web相关的内容,主要实现:
-
Http支持
-
设置Kestrol服务器为Web服务器
-
添加IIS支持
加入Web主机,也是一个方法 ConfigureWebHostDefaults
:
class Program { static void Main(string[] args) { Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { }) .Build() .Run(); } }
这个方法用来添加Http请求管道并注入我们需要的服务。而注入我们需要的服务,就是我们最常见的 Startup.cs
的内容。
下面,我们先创建 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
现在还是空的。
3. 补齐Startup类
Startup
类在Asp.net Core应用中有着重要的作用。这个类用于:
-
使用DI容器注入服务
-
设置Http Request管道以插入中间件
下面我们补齐所需的方法:
namespace demo { public class Startup { public void ConfigureServices(IServiceCollection services) { } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { } } }
运行,到这儿,Web应用已经可以正常启动了。
4. 给应用添加路由
Web应用启动了,但里面什么也没有,是空的。
要访问Web应用中的任何资源,需要配置路由。这儿的路由,基本上就是传入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应用转为了Web应用。
三、延伸内容
上面完成的Web应用,算是Web应用中的基础。基于这个内容,我们还可以扩展到别的项目结构。
1. 改为MVC应用
需要在 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应用
需要注入 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应用
需要注入 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(); }); } }
四、总结
看下来,其实过程很简单。通过这种方式,能更进一步理解Dotnet Core的项目结构以及应用的运行过程。
希望对大家能有所帮助。
本文的配套代码在:https://github.com/humornif/Demo-Code/tree/master/0038/demo
喜欢就来个三连,让更多人因你而受益
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK