添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
  • 持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天, 点击查看活动详情
  • Visual Studio(2022) 创建的 ASP.NET Core 或者使用 SDK(.NET6.0) 创建的应用使用顶级语句。
  • C# 9 之前,程序的入口点为 Main 的静态方法。

    static void Main(string[] args) 
        Console.WriteLine("Hello world"); 
    

    C# 9 开始,无需在控制台应用程序项目中显式包含 Main 方法。

    Console.WriteLine("Hello World");
    

    如上是.NET 6 / C# 10 创建项目程序结构的一些变化,不要觉得陌生,个人觉得这也是一大优化点。使用顶级语句功能最大程度地减少必须编写的代码,但是值得注意的有几点:

  • 只能有一个顶级文件:即一个程序只能存在一个入口
  • 顶级语句可以引用 args 变量来访问输入的任何命令行参数(永远不会为 null),但如果未提供任何命令行参数,则其 Length 将为零。
  • 顶级语句的文件还可以包含命名空间和类型定义,但它们必须位于顶级语句之后
  • 可以直接使用await调用异步方法
  • 如果包含 using 指令,则它们必须首先出现在文件中
  • 了解了这些变化之后就让我们一起来探索我们ASP.NET Core是如何启动的,并且启动过程中都做了哪些事情吧。

    Program 类

    Program.cs 为模板创建.NET Core应用程序的启动代码

  • WebApplication.CreateBuilder(args)
  • /// <summary>
    /// Initializes a new instance of the class with preconfigured defaults.
    /// </summary>
    public static WebApplicationBuilder CreateBuilder(string[] args) =>
        new(new() { Args = args });
    

    简单点说就是创建一个WebApplicationBuilder实例

  • build.Services
  • 主要做的就是将服务添加到 DI 容器中,在创建WebApplicationBuilder实例的时候会添加许多框架提供的服务。

    // 以AddControllers为例,为指定的控制器添加服务至容器中
    builder.Services.AddControllers();
    // 此处为AddControllers扩展方法源码
    public static IMvcBuilder AddControllers(this IServiceCollection services)
        if (services == null)
            throw new ArgumentNullException(nameof(services));
        // 添加Controllers核心服务
        var builder = AddControllersCore(services);
        // return MvcBuilder实例
        return new MvcBuilder(builder.Services, builder.PartManager);
    // AddControllersCore 源码
    private static IMvcCoreBuilder AddControllersCore(IServiceCollection services)
        // This method excludes all of the view-related services by default.
        var builder = services
            .AddMvcCore() //将最小基本 MVC 服务添加到 IServiceCollection
            .AddApiExplorer() // 配置为使用 ApiExplorer。
            .AddAuthorization() // 配置认证授权服务
            .AddCors() // 配置跨域
            .AddDataAnnotations() // 注册MVC数据注释。
            .AddFormatterMappings(); // 添加服务以支持 FormatterMappings(用于指定 URL 格式与相应媒体类型之间的映射)
        if (MetadataUpdater.IsSupported)
            // 注册支持同一服务类型的多个注册的服务类型的服务
            services.TryAddEnumerable(
                ServiceDescriptor.Singleton<IActionDescriptorChangeProvider, HotReloadService>());
        return builder;
    
  • builder.Build() 这一段源码太长就不一一拉出来看,大家如果感兴趣也可以去研究研究
  • 构造一个 WebApplication 实例。

  • 设置构造主机的配置。
  • 将已经构建的配置提供程序复制到最终的配置生成器,连接应用程序配置。
  • 为构建过程和应用程序的其余部分设置配置。
  • 复制WebApplicationBuilder添加的服务
  • WebApplicationBuilder.Build 方法使用一组默认选项配置主机,例如:

  • 将 Kestrel 用作 Web 服务器并启用 IIS 集成。
  • 从 appsettings.json、环境变量、命令行参数和其他配置源中加载配置
  • 将日志记录输出发送到控制台并调试提供程序。
  • ASP.NET Core 在应用启动时读取该环境变量,并将该值存储在 IWebHostEnvironment 实现中

    // 如果是Develop环境 则配置Swagger中间件
    if (app.Environment.IsDevelopment())
        app.UseSwagger();
        app.UseSwaggerUI();
    

    请求处理管道由一系列中间件组件组成,通过调用 Use{Feature} 扩展方法,向管道添加中间件组件

  • 什么是中间件:
  • 中间件是一种装配到应用管道以处理请求和响应的软件。 每个组件:

  • 选择是否将请求传递到管道中的下一个组件。
  • 可在管道中的下一个组件前后执行工作。
  • 至此就是整个ASP.NET Core运行的整个流程,当然这其中也包括了许多ASP.NET Core 应用的基础知识,包括依赖关系注入 (DI)、配置、中间件,要想真正了解,还得多看看源码实现,只有了解了基础你在自己研究框架的时候才能更加的轻松、游刃有余。

  • 文末彩蛋 .NET Core 为什么能跨平台?
  • CreateBuilder 内部调用了 UseKestrel(IWebHostBuilder)Kestrel 服务器 是默认跨平台 HTTP 服务器实现。 Kestrel 提供了最佳性能和内存利用率,但它没有 HTTP.sys 中的某些高级功能。

  • 本身作为边缘服务器,处理直接来自网络(包括 Internet)的请求。
  • 私信