ASP.NET Core Program.cs

.NET 8 中 Program.cs 的标准结构详解

一个典型的 .NET 8 Web 应用 Program.cs 看起来像这样:

// .NET 8 Program.cs - Minimal API 风格
var builder = WebApplication.CreateBuilder(args);

// 1. 配置服务 (依赖注入 DI Container)
// --------------------------------
builder.Services.AddControllers(); // 添加 MVC 控制器服务(如果使用)
builder.Services.AddEndpointsApiExplorer(); // 添加 API Explorer 服务(通常用于 Swagger)
builder.Services.AddSwaggerGen(); // 添加 Swagger 生成器服务
builder.Services.AddScoped<IMyService, MyService>(); // 注册自定义服务
// ... 其他服务注册 (数据库上下文、身份认证、授权、缓存等)

// 2. 构建应用程序实例
// --------------------------------
var app = builder.Build();

// 3. 配置中间件管道 (HTTP Request Pipeline)
// --------------------------------
if (app.Environment.IsDevelopment())
{
    app.UseSwagger(); // 开发环境:提供 Swagger JSON 端点
    app.UseSwaggerUI(); // 开发环境:提供 Swagger UI 界面
}

app.UseHttpsRedirection(); // 将 HTTP 请求重定向到 HTTPS
app.UseAuthorization(); // 启用授权中间件
// app.UseAuthentication(); // 如果需要认证,通常放在 UseAuthorization 前面
// app.UseStaticFiles(); // 启用静态文件服务
// app.UseRouting(); // 在 Minimal API 中通常隐式包含,显式调用也可

// 4. 配置端点 (路由)
// --------------------------------
// 方式 A: 使用 Minimal API 直接定义端点
app.MapGet("/", () => "Hello World from Minimal API!"); // GET /
app.MapGet("/api/users", (IMyService service) => service.GetUsers()); // GET /api/users,演示依赖注入
app.MapPost("/api/users", (User user) => Results.Created($"/api/users/{user.Id}", user)); // POST /api/users

// 方式 B: 使用控制器 (如果添加了 AddControllers)
app.MapControllers(); // 映射所有用 [ApiController] 和 [Route] 等属性标记的控制器

// 5. 运行应用程序
// --------------------------------
app.Run(); // 启动应用程序并开始监听请求

关键组成部分详解

  1. var builder = WebApplication.CreateBuilder(args);

    • 这是入口点。它创建了一个 WebApplicationBuilder 实例。
    • args 接收命令行参数。
    • builder 对象是配置的起点,它提供了:
      • Configuration:访问 appsettings.json、环境变量、命令行参数等配置源。
      • Services (IServiceCollection):用于注册应用程序所需的所有服务(依赖注入)。这是替代传统 Startup.ConfigureServices 的地方。
      • Logging:配置日志记录提供程序。
      • Host / WebHost:配置主机设置(较少需要手动配置)。
  2. 服务注册 (builder.Services.AddXxx())

    • 使用 builder.Services 这个 IServiceCollection 来添加应用程序所需的服务。
    • 常见的服务注册方法:
      • AddControllers() / AddControllersWithViews():注册 MVC 控制器服务(如果你选择使用 Controller 而不是纯 Minimal API 端点)。
      • AddEndpointsApiExplorer():为 Minimal API 或 Web API 添加 API 描述服务,是 Swagger/OpenAPI 的基础。
      • AddSwaggerGen():注册 Swagger 生成器,用于生成 OpenAPI 文档。
      • AddDbContext<MyDbContext>():注册 Entity Framework Core 数据库上下文。
      • AddIdentity<IdentityUser, IdentityRole>():注册 ASP.NET Core Identity 服务。
      • AddAuthentication() / AddJwtBearer():注册认证服务。
      • AddAuthorization():注册授权服务(通常与认证一起使用)。
      • AddScoped<TService, TImplementation>() / AddTransient<...> / AddSingleton<...>:注册自定义服务,指定生命周期。
    • 所有依赖注入容器的配置都在这里完成。
  3. var app = builder.Build();

    • 在完成所有服务注册后,调用 Build() 方法。
    • 这个方法根据之前的配置构建出实际的 WebApplication 实例 (app)。
    • app 对象代表你的应用程序本身,用于配置中间件管道路由。这是替代传统 Startup.Configure 的地方。
  4. 配置中间件管道 (app.UseXxx())

    • 中间件是处理 HTTP 请求和响应的组件,按添加到管道的顺序执行。
    • 使用 app.UseXxx() 方法将中间件添加到管道中。
    • 顺序至关重要! 中间件按照添加的顺序执行。例如:
      • 异常处理 (UseExceptionHandler) 通常应放在最前面,以便捕获后续中间件的所有异常。
      • HTTPS 重定向 (UseHttpsRedirection) 应在处理敏感数据(如认证、静态文件)之前。
      • 静态文件 (UseStaticFiles) 通常放在认证之前,因为像图片、CSS 这些静态文件通常不需要认证。
      • 路由 (UseRouting):在 Minimal API 中,MapXxx 方法内部通常会处理路由,显式调用 UseRouting() 是可选的,但有时为了明确位置会加上。它负责将请求匹配到端点。
      • 认证 (UseAuthentication):必须在授权 (UseAuthorization) 之前调用,用于识别用户身份。
      • 授权 (UseAuthorization):根据认证结果和策略决定用户是否有权访问资源。
      • 端点 (UseEndpoints):在传统 MVC 中显式使用,在 Minimal API 中被 MapXxx 方法替代。
    • 环境判断 (if (app.Environment.IsDevelopment())) 常用于只在开发环境启用的中间件,如 Swagger UI、详细的错误页面。
  5. 配置端点 (app.MapXxx())

    • 这是定义应用程序如何响应特定 URL 和 HTTP 方法(GET, POST, PUT, DELETE 等)的地方。
    • Minimal API 方式: 使用 MapGet(), MapPost(), MapPut(), MapDelete(), MapMethods() 等方法直接在 Program.cs 中定义端点及其处理程序(通常是 Lambda 表达式或方法)。处理程序可以:
      • 直接返回结果(字符串、JSON 对象、IResultResults.Ok(), Results.NotFound(), Results.Created())。
      • 通过参数注入依赖的服务(由 DI 容器自动提供)。
      • 访问 HttpContext
      • 使用模型绑定从请求体、查询字符串、路由数据等获取参数。
    • 控制器方式: 如果之前调用了 AddControllers(),则可以使用 app.MapControllers() 来映射所有遵循 MVC 模式的控制器类(使用 [ApiController], [Route], [HttpGet] 等属性)。这种方式更适合大型或复杂 API 的组织。
  6. app.Run();

    • 这是应用程序的终点。调用 Run() 方法会启动 Kestrel 服务器(或其他配置的主机),开始监听传入的 HTTP 请求。
    • 应用程序会一直运行,直到被关闭(Ctrl+C 或系统信号)。