• ASP.NET Core 的启动和运行机制


    ASP .NET Core 的运行机制

    core web server

    1. Web Server: ASP.NET Core 提供两种服务器可用, 分别是 Kestrel 和 HTTP.sys (Core 1.x 中被命名为 WebListener),
      • Kestrel是一个跨平台的Web服务器。
      • HTTP.sys只能用在Windows系统中.
    2. Internet: 当需要部署在Internal Network 中并需要 Kestrel 中没有的功能(如 Windows 身份验证)时,可以选择HTTP.sys。
    3. IIS、Apache、Nginx: Kestrel 可以单独使用 ,也可以将其与反向代理服务器(如 IIS、Nginx 或 Apache)结合使用。 请求经这些服务器进行初步处理后转发给Kestrel(即图中虚线的可选流程).

    ASP .NET Core 的启动

    core startup

    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }
    
        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
    
    1. Main: 程序的起点. ASP .NET Core 应用程序本质上是控制台应用程序。
    2. CreateDefaultBuilder:创建并配置WebHostBuilder, 首先调用Create­DefaultBuilder( 如图所示, 它是一系列配置的大综合,下文做详细介绍), 进行一系列配置。
    3. UseStartup: 指定Startup为启动配置文件. 在Startup中, 将进行两个比较重要的工作, 服务的依赖注入和配置管道。
      1. ConfigureServices方法是注册服务
      2. Configure方法是配置管道,用来具体指定如何处理每个http请求的, 例如我们可以让这个程序知道我使用mvc来处理http请求, 那就调用app.UseMvc()这个方法就行.
    4. BuildWebHost:生成WebHostBuilder并进行了一系列配置之后, 通过这个WebHostBuilder来Build出一个IWebHost。
    5. Run:调用IWebHost的Run方法使之开始运行。

    Create­DefaultBuilder

    public static IWebHostBuilder CreateDefaultBuilder(string[] args)
    {
        var builder = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                var env = hostingContext.HostingEnvironment;
    
                config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
    
                if (env.IsDevelopment())
                {
                    var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
                    if (appAssembly != null)
                    {
                        config.AddUserSecrets(appAssembly, optional: true);
                    }
                }
    
                config.AddEnvironmentVariables();
    
                if (args != null)
                {
                    config.AddCommandLine(args);
                }
            })
            .ConfigureLogging((hostingContext, logging) =>
            {
                logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                logging.AddConsole();
                logging.AddDebug();
            })
            .UseIISIntegration()
            .UseDefaultServiceProvider((context, options) =>
            {
                options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
            });
    
        return builder;
    }
    
    • UseKestrel 指定服务器使用 Kestrel,若使用HttpSys,需使用UseHttpSys。
    • UseContentRoot 指定根目录
    • ConfigureAppConfiguration 读取配置文件
    • ConfigureLogging 配置日志处理程序
    • UseIISIntegration 将应用程序配置为在 IIS 中运行。如果应用程序没有使用 IIS 作为反向代理,那么 UseIISIntegration 不会有任何效果。因此,即使应用程序在非 IIS 方案中运行,也可以安全调用这种方法。
    • UseDefaultServiceProvider 设置默认的依赖注入容器。

    ASP .NET Core 的管道和中间件

    请求管道: 那些处理http requests并返回responses的代码组成了request pipeline(请求管道).

    中间件: 我们可以使用一些程序来配置请求管道(request pipeline)以便处理requests和responses. 比如处理验证(authentication)的程序, MVC本身就是个中间件(middleware).

    当接收到一个请求时,请求会交给中间件构成的中间件管道进行处理,管道就是多个中间件构成,请求从一个中间件的一端进入,从中间件的另一端出来,每个中间件都可以对HttpContext请求开始和结束进行处理.

    Middleware

    自己写一个中间件测试下:

    1. 通过约定方法实现:

      public class Floor1Middleware
      {
          private readonly RequestDelegate _next;
      
          public Floor1Middleware(RequestDelegate next)
          {
              _next = next;
          }
      
          public async Task InvokeAsync(HttpContext context)
          {
              Console.WriteLine("Floor1Middleware In");
              //Do Something
              //To FloorTwoMiddleware
              await _next(context);
              //Do Something
              Console.WriteLine("Floor1Middleware Out");
          }
      }
      

      添加扩展方法:

      public static class Floor1MiddlewareExtensions
      {
          public static IApplicationBuilder UseFloor1Middleware(this IApplicationBuilder builder)
          {
              return builder.UseMiddleware<Floor1Middleware>();
          }
      }
      
    2. 通过 IMiddleware 实现

      public class Floor3Middleware : IMiddleware
      {
          public async Task InvokeAsync(HttpContext context, RequestDelegate next)
          {
              Console.WriteLine("Floor3Middleware In");
              //Do Something
              //To FloorTwoMiddleware
              await next(context);
              //Do Something
              Console.WriteLine("Floor3Middleware Out");
          }
      }
      
      public static class MiddlewareExtensions
      {
          public static IApplicationBuilder UseFloor3Middleware(
              this IApplicationBuilder builder)
          {
              return builder.UseMiddleware<Floor3Middleware>();
          }
      }
      
      public void ConfigureServices(IServiceCollection services)
      {
          services.AddTransient<Floor3Middleware>();
      
          services.AddMvc();
      }
      
    3. 也可以用简要的写法,直接在Startup的Configure方法中这样写:

      app.Use(async (context, next) =>
      {
          Console.WriteLine("Floor2Middleware In");
      
          await next.Invoke();
      
          Console.WriteLine("Floor2Middleware Out");
      });
      
    4. 测试中间件:

      public void Configure(IApplicationBuilder app, IHostingEnvironment env)
      {
          app.UseFloor1Middleware();
      
          app.Use(async (context, next) =>
          {
              Console.WriteLine("Floor2Middleware In");
      
              await next.Invoke();
      
              Console.WriteLine("Floor2Middleware Out");
          });
      
          if (env.IsDevelopment())
          {
              app.UseDeveloperExceptionPage();
          }
          else
          {
              app.UseExceptionHandler("/Home/Error");
          }
      
          app.UseStaticFiles();
          app.UseCookiePolicy();
      
          app.UseMvc(routes =>
          {
              routes.MapRoute(
                  name: "default",
                  template: "{controller=Home}/{action=Index}/{id?}");
          });
      }
      

      运行查看输出为:

      DIDemo> Floor1Middleware In
      DIDemo> Floor2Middleware In
      DIDemo> Floor3Middleware In
      DIDemo> info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      DIDemo>       Route matched with {action = "Index", controller = "Home"}. Executing action DIDemo.Controllers.HomeController.Index (DIDemo)
      DIDemo> info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      DIDemo>       Executing action method DIDemo.Controllers.HomeController.Index (DIDemo) - Validation state: Valid
      DIDemo> info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      DIDemo>       Executed action method DIDemo.Controllers.HomeController.Index (DIDemo), returned result Microsoft.AspNetCore.Mvc.ViewResult in 0.1167ms.
      DIDemo> info: Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor[1]
      DIDemo>       Executing ViewResult, running view Index.
      DIDemo> info: Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor[4]
      DIDemo>       Executed ViewResult - view Index executed in 3.3508ms.
      DIDemo> info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      DIDemo>       Executed action DIDemo.Controllers.HomeController.Index (DIDemo) in 9.5638ms
      DIDemo> Floor3Middleware Out
      DIDemo> Floor2Middleware Out
      DIDemo> Floor1Middleware Out
      

    参考

  • 相关阅读:
    C字符串格式化
    oms登录bug
    宏旺文章审核功能使用指引
    phpcms文章审核
    html5的pushState 无刷新, 前进后退等
    js路由—backbone的路由的实现02
    js路由—backbone的路由的实现01
    js路由—简单路由的实现
    img标签和css的background-image的区别
    querySelector与querySelectorAll
  • 原文地址:https://www.cnblogs.com/royzshare/p/9442666.html
Copyright © 2020-2023  润新知