ASP.NET Core 6 基础入门系列(11)项目结构详解之项目入口Program.cs

 

在传统的 ASP.NET WebForm 项目中,入口文件为开发者指定的起始页(.aspx),可以指定任意页面为起始页。

 

传统的 ASP.NET MVC 项目中,入口文件为Global.asax,里面注册了默认的路由,首次访问时根据路由配置导航到指定的Controller与Action。开发者可以自定义配置路由信息。

传统的 Console 控制台项目中,入口文件为 Program.cs 文件

传统的  WinForm 桌面项目中,入口文件为 Program.cs 文件

Console 与 WinForm 项目的入口文件都是  Program.cs ,且里面的入口方法都是 Main() 函数。事实上使用 Main() 函数做为程序的入口方法是许多编程语言的惯例,如C++、Java等。

在 ASP.NET Core 6.0 项目中,入口文件也是 Program.cs 文件。 

打开并查看Program.cs文件内容如下:

第一次接触的开发者会产生很大的疑惑,Program.cs 文件中既没有定义类,也没有定义方法。我们编译项目,然后使用反编译工具dnSpy来查看编译后的代码

编译后的代码,第9行定义了类,名称与Progress.cs文件名相同;第12行出现了Main()函数,VS中的Program.cs文件中的代码被包含在该Main()方法体中,这里就涉及到一个知识点,C#9.0中的新语法 - 顶级语句

顶级语句的语法出现之前,在控制台中打印 Hello World 的全部代码如下:

复制代码
 1 using System;
 2 
 3 namespace HelloWorld
 4 {
 5     class Program
 6     {
 7         static void Main(string[] args)
 8         {
 9             Console.WriteLine("Hello World!");
10         }
11     }
12 }
复制代码

顶级语句从许多应用程序中删除了不必要的流程。 借助顶级语句,只有一行代码执行所有操作。可使用 using 指令和执行操作的一行替换所有样本:

1 using System;
2 
3 Console.WriteLine("Hello World!");

如果需要单行程序,可删除 using 指令,并使用完全限定的类型名称:

System.Console.WriteLine("Hello World!");

  应用程序中只有一个文件可使用顶级语句。 如果编译器在多个源文件中找到顶级语句,则是错误的。 如果将顶级语句与声明的程序入口点方法(通常为 Main 方法)结合使用,也会出现错误。 从某种意义上讲,可认为一个文件包含通常位于 Program 类的 Main 方法中的语句。

  此功能最常见的用途之一是创建材料。 C# 初级开发人员可以用一两行代码编写规范的“Hello World!”。 不需要额外的工作。 不过,经验丰富的开发人员还会发现此功能的许多用途。 顶级语句可提供类似脚本的试验体验,这与 Jupyter 笔记本提供的很类似。 顶级语句非常适合小型控制台程序和实用程序。 Azure Functions 是顶级语句的理想用例。

  最重要的是,顶层语句不会限制应用程序的范围或复杂程度。 这些语句可访问或使用任何 .NET 类。 它们也不会限制你对命令行参数或返回值的使用。 顶级语句可访问名为 args 的字符串数组。 如果顶级语句返回整数值,则该值将成为来自合成 Main 方法的整数返回代码。 顶级语句可能包含异步表达式。 在这种情况下,合成入口点将返回 Task 或 Task<int>

  • 有关详细信息,请参阅 C# 编程指南中的顶级语句《顶级语句 - 不使用 Main 方法的程序》https://docs.microsoft.com/zh-cn/dotnet/csharp/fundamentals/program-structure/top-level-statements
  • 关于C#9.0的新增语法及特性,请参考微软官方文档:https://docs.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-9#top-level-statements

Program.cs 文件实现两大功能

  • 配置应用所需的服务
  • 将应用的请求处理管道定义为一系列中间件组件

支持以下应用启动代码:

 Program.cs 文件内容虽然简洁,但是包含了丰富的内容,如依赖关系注入 (DI)、配置、中间件等等

复制代码
 1 var builder = WebApplication.CreateBuilder(args);
 2 
 3 // 向容器中添加服务
 4 builder.Services.AddRazorPages();
 5 builder.Services.AddControllersWithViews();
 6 
 7 var app = builder.Build();
 8 
 9 // 配置HTTP请求管道
10 if (!app.Environment.IsDevelopment())
11 {
12     app.UseExceptionHandler("/Home/Error");
13 
14     // 默认的 HSTS 值为30天。如果需要为生产环境更改此设置,请参考:https://aka.ms/aspnetcore-hsts.
15     app.UseHsts();
16 }
17 
18 app.UseHttpsRedirection();
19 
20 app.UseStaticFiles(); // 访问默认静态文件,需要注册此中间件
21 
22 app.UseRouting(); // 使用路由中间件
23 
24 app.UseAuthorization();
25 
26 app.MapControllerRoute(
27     name: "default",
28     pattern: "{controller=Home}/{action=Index}/{id?}"); // 默认的路由
29 
30 app.Run();
复制代码
 1、依赖关系注入(服务)

  ASP.NET Core 包括依赖关系注入(Dependency Injection,简称DI)功能,它使配置的服务在整个应用程序中可用。

第1行代码通过使用预配置的命令行参数创建了一个WebApplicationBuilder对象。在此过程中 builder对象 已将配置、日志记录和许多其他服务添加到 DI 容器中。

第4、5行代码 builder.Services.AddXXXX() 方法将各种服务添加到 DI 容器中。

实例化 WebApplicationBuilder 过程中,会添加许多 框架提供的服务

  通常使用构造函数注入从 DI 解析服务。 DI 框架在运行时提供此服务的实例。以下代码使用构造函数注入从 DI 解析日志记录器:

2、中间件

  请求处理管道由一系列中间件组件组成。 每个组件在 HttpContext 上执行操作,调用管道中的下一个中间件或终止请求。按照惯例,通过调用 Use{Feature} 扩展方法,向管道添加中间件组件。

有关详细信息,请参阅 ASP.NET Core 中间件

3、主机

ASP.NET Core 应用在启动时构建主机。 主机封装应用的所有资源,例如:

  • HTTP 服务器实现
  • 中间件组件
  • Logging
  • 依赖关系注入 (DI) 服务
  • Configuration

有三个不同的主机:

建议使用 .NET WebApplication 主机,并在所有 ASP.NET Core 模板中使用。 .NET WebApplication Host 主机和 .NET Generic Host  通用主机共享许多相同的接口和类。 ASP.NET Core Web 主机仅用于支持后向兼容性。

以下代码将 WebApplication 主机实例化:

var app = builder.Build();

WebApplicationBuilder.Build 方法使用一组默认选项配置主机,例如:

  • 将 Kestrel 用作 Web 服务器并启用 IIS 集成。
  • 从 appsettings.json、环境变量、命令行参数和其他配置源中加载配置
  • 将日志记录输出发送到控制台并调试提供程序。

非 Web 方案

其他类型的应用可通过 .NET Generic Host 通用主机使用横切框架扩展,例如日志记录、依赖项注入 (DI)、配置和应用生命周期管理。 有关详细信息,请参阅 ASP.NET Core 中的 .NET 通用主机 和 ASP.NET Core 中使用托管服务的后台任务

4、服务器

ASP.NET Core 应用使用 HTTP 服务器实现侦听 HTTP 请求。 服务器对应用的请求在表面上呈现为一组由 HttpContext 组成的请求功能

(1)Windows 平台

  ASP.NET Core 提供以下服务器实现:

  • Kestrel 是跨平台 Web 服务器。 Kestrel 通常使用 IIS 在反向代理配置中运行。 在 ASP.NET Core 2.0 或更高版本中,Kestrel 可作为面向公众的边缘服务器运行,直接向 Internet 公开。
  • IIS HTTP 服务器 适用于使用 IIS 的 Windows。 借助此服务器,ASP.NET Core 应用和 IIS 在同一进程中运行。
  • HTTP.sys 是适用于不与 IIS 一起使用的 Windows 的服务器。

(2)Linux、macOS平台

  ASP.NET Core 提供 Kestrel 跨平台服务器实现。 在 ASP.NET Core 2.0 或更高版本中,Kestrel 可作为面向公众的边缘服务器运行,直接向 Internet 公开。 Kestrel 通常使用 Nginx 或 Apache 在反向代理配置中运行。

有关详细信息,请参阅 ASP.NET Core 中的 Web 服务器实现

5、配置

  ASP.NET Core 提供了配置框架,可以从配置提供程序的有序集中将设置作为名称/值对。 可将内置配置提供程序用于各种源,例如 .json 文件、.xml 文件、环境变量和命令行参数。 可编写自定义配置提供程序以支持其他源。

默认情况下,ASP.NET Core 应用配置为从 appsettings.json、环境变量和命令行等读取内容。 加载应用配置后,来自环境变量的值将替代来自 appsettings.json 的值。

  为了管理密码等机密配置数据,.NET Core 提供了机密管理器。 对于生产机密,建议使用 Azure 密钥保管库

  有关详细信息,请参阅 ASP.NET Core 中的配置

6、环境

  执行环境(例如 DevelopmentStaging 和 Production)在 ASP.NET Core 中可用。 通过设置 ASPNETCORE_ENVIRONMENT 环境变量来指定应用的运行环境。 ASP.NET Core 在应用启动时读取该环境变量,并将该值存储在 IWebHostEnvironment 实现中。 通过依赖关系注入 (DI),可以在应用中任何位置实现此操作。

  以下示例未在 Development 环境中运行时配置异常处理程序和 HTTP 严格传输安全协议 (HSTS) 中间件:

7、日志

ASP.NET Core 支持适用于各种内置和第三方日志记录提供程序的日志记录 API。 可用的提供程序包括:

  • 控制台
  • 调试
  • Windows 事件跟踪
  • Windows 事件日志
  • TraceSource
  • Azure 应用服务
  • Azure Application Insights

若要创建服务,请从依赖关系注入 (DI) 解析 ILogger<TCategoryName> 服务,并调用 LogInformation 等日志记录方法。 例如:

有关详细信息,请参阅 .NET Core 和 ASP.NET Core 中的日志记录

8、路由

  路由是映射到处理程序的 URL 模式。 处理程序通常是 Razor 页面、MVC 控制器中的操作方法或中间件。 借助 ASP.NET Core 路由,可以控制应用使用的 URL。以下由 ASP.NET Core Web 应用程序模板生成的代码调用 UseRouting

有关详细信息,请参阅 ASP.NET Core 中的路由

9、错误处理

ASP.NET Core 具有用于处理错误的内置功能,例如:

  • 开发人员异常页
  • 自定义错误页
  • 静态状态代码页
  • 启动异常处理

有关详细信息,请参阅处理 ASP.NET Core 中的错误

10、发出HTTP请求

IHttpClientFactory 的实现可用于创建 HttpClient 实例。 工厂可以:

  • 提供一个中心位置,用于命名和配置逻辑 HttpClient 实例。 例如,注册并配置 github 客户端以访问 GitHub。 注册并配置默认客户端以实现其他目的。
  • 支持多个委托处理程序的注册和链接,以生成出站请求中间件管道。 此模式类似于 ASP.NET Core 的入站中间件管道。 此模式提供了一种用于管理 HTTP 请求相关问题的机制,包括缓存、错误处理、序列化以及日志记录。
  • 与 Polly 集成,这是用于瞬时故障处理的常用第三方库。
  • 管理基础 HttpClientHandler 实例的池和生存期,避免手动管理 HttpClient 生存期时可能出现的常见 DNS 问题。
  • 通过 ILogger 添加可配置的日志记录体验,用于记录通过工厂创建的客户端发送的所有请求。
builder.Services.AddHttpClient();

有关详细信息,请参阅在 ASP.NET Core 中使用 IHttpClientFactory 发出 HTTP 请求

11、ContentRoot 内容根

ContentRoot是指向以下内容的基路径:

  • 托管应用的可执行文件 (.exe)。
  • 构成应用程序的已编译程序集 (.dll)。
  • 应用使用的内容文件,例如:
    • Razor 文件(.cshtml.razor
    • 配置文件(.json.xml
    • 数据文件 (.db)
  • Web 根目录,通常是 wwwroot 文件夹。

在开发中,内容根目录默认为项目的根目录。 此目录还是应用内容文件和 Web 根目录的基路径。 在构建主机时设置路径,可指定不同的内容根目录。 有关详细信息,请参阅内容根


参考文献:

  • 《.NET6 应用启动》https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/?view=aspnetcore-6.0&tabs=windows
posted @   张传宁  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
页脚 HTML 代码
点击右上角即可分享
微信分享提示