• asp.net core 系列 2 启动类 Startup.CS


    学无止境,精益求精

    十年河东,十年河西,莫欺少年穷

    学历代表你的过去,能力代表你的现在,学习代表你的将来

    在探讨Startup启动类之前,我们先来了解下Asp.NET CORE 配置应用程序的执行顺序,如下图所示

    与早期版本的 ASP.NET 对比,最显著的变化之一就是配置应用程序的方式, Global.asax、FilterConfig.cs 和 RouteConfig.cs 统统消失了,取而代之的是 Program.cs 和 Startup.cs。Program.cs 作为 Web 应用程序的默认入口,不做任何修改的情况下,会调用同目录下 Startup.cs 中的 ConfigureServices 方法 和 Configure 方法。

     首先我们来看下Progarm.cs,如下

        public class Program
        {
            public static void Main(string[] args)
            {
                CreateWebHostBuilder(args).Build().Run();
            }
    
            public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
                WebHost.CreateDefaultBuilder(args)
                    .UseStartup<Startup>();
        }
    View Code

    我们看到Program中Main函数很像我们之前的Console应用程序,那么它当中的CreateWebHostBuilder究竟做了什么事情呢?既然.Net Core是开源的,我们看源码就方便了很多,接下来就从源码来了解下它究竟做了什么工作。

    /// <summary>
            /// Initializes a new instance of the <see cref="WebHostBuilder"/> class with pre-configured defaults.
            /// </summary>
            /// <remarks>
            ///   The following defaults are applied to the returned <see cref="WebHostBuilder"/>:
            ///     use Kestrel as the web server and configure it using the application's configuration providers,
            ///     set the <see cref="IHostingEnvironment.ContentRootPath"/> to the result of <see cref="Directory.GetCurrentDirectory()"/>,
            ///     load <see cref="IConfiguration"/> from 'appsettings.json' and 'appsettings.[<see cref="IHostingEnvironment.EnvironmentName"/>].json',
            ///     load <see cref="IConfiguration"/> from User Secrets when <see cref="IHostingEnvironment.EnvironmentName"/> is 'Development' using the entry assembly,
            ///     load <see cref="IConfiguration"/> from environment variables,
            ///     load <see cref="IConfiguration"/> from supplied command line args,
            ///     configure the <see cref="ILoggerFactory"/> to log to the console and debug output,
            ///     and enable IIS integration.
            /// </remarks>
            /// <param name="args">The command line args.</param>
            /// <returns>The initialized <see cref="IWebHostBuilder"/>.</returns>
            public static IWebHostBuilder CreateDefaultBuilder(string[] args)
            {
                var builder = new WebHostBuilder();
    
                if (string.IsNullOrEmpty(builder.GetSetting(WebHostDefaults.ContentRootKey)))
                {
                    builder.UseContentRoot(Directory.GetCurrentDirectory());
                }
                if (args != null)
                {
                    builder.UseConfiguration(new ConfigurationBuilder().AddCommandLine(args).Build());
                }
    
                builder.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();
                    logging.AddEventSourceLogger();
                }).
                UseDefaultServiceProvider((context, options) =>
                {
                    options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
                });
    
                ConfigureWebDefaults(builder);
    
                return builder;
            }
    View Code
    internal static void ConfigureWebDefaults(IWebHostBuilder builder)
            {
                builder.UseKestrel((builderContext, options) =>
                {
                    options.Configure(builderContext.Configuration.GetSection("Kestrel"));
                })
                .ConfigureServices((hostingContext, services) =>
                {
                    // Fallback
                    services.PostConfigure<HostFilteringOptions>(options =>
                    {
                        if (options.AllowedHosts == null || options.AllowedHosts.Count == 0)
                        {
                            // "AllowedHosts": "localhost;127.0.0.1;[::1]"
                            var hosts = hostingContext.Configuration["AllowedHosts"]?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                            // Fall back to "*" to disable.
                            options.AllowedHosts = (hosts?.Length > 0 ? hosts : new[] { "*" });
                        }
                    });
                    // Change notification
                    services.AddSingleton<IOptionsChangeTokenSource<HostFilteringOptions>>(
                                new ConfigurationChangeTokenSource<HostFilteringOptions>(hostingContext.Configuration));
    
                    services.AddTransient<IStartupFilter, HostFilteringStartupFilter>();
    
                    services.AddRouting();
                })
                .UseIIS()
                .UseIISIntegration();
            }
    View Code

    从源码中我们可以看到,CreateDefaultBuilder执行的任务有:

      1、加载主机和应用程序的配置表信息

      2、配置日志记录

      3、设置Web服务器

      4、设置Asp.Net Core应用程序的托管形式。

    Asp.Net Core应用程序的托管形式,它有两种托管形式:进程内托管InProcess和进程外托管OutOfProcess。我们知道Asp.Net Core是可以自托管的,它默认托管形式就是InProcess。那么这两种方式的区别是什么呢?

    InProcess:配置进程内托管在项目.csproj文件中 <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>,在InProcess托管情况下,CreateDefaultBuilder()方法调用UseIIS()方法并在IIS工作进程(w3wp.exe或iisexpress.exe)内托管应用程序,从性能角度,InProcess托管比OutOfProcess托管提供了更高的请求吞吐量。

    OutOfProcess:有2个Web服务器-内部Web服务器和外部Web服务器,内部Web服务器是Kestrel,托管进程是dotnet.exe;外部web服务器可以是iis,nginx,apache。

    总之,我们可以初步理解为Program.cs 主要用来构造,配置,并启用项目所依赖的服务器,最后设置Asp.Net Core应用程序的托管形式。

    在Program.cs中,我们发现它会引用Startup.CS,如下:

      public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
                WebHost.CreateDefaultBuilder(args)
                    .UseStartup<Startup>();

    下面我们来看看启动类Startup.CS,如下:

        public class Startup
        {
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            public IConfiguration Configuration { get; }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.Configure<CookiePolicyOptions>(options =>
                {
                    // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                    options.CheckConsentNeeded = context => true;
                    options.MinimumSameSitePolicy = SameSiteMode.None;
                });
    
    
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    //如果是开发环境,允许抛出异常
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    //生产环境,直接错误页
                    app.UseExceptionHandler("/Error");
                    app.UseHsts();
                }
    
                app.UseHttpsRedirection();
                app.UseStaticFiles();
                app.UseCookiePolicy();
    
                app.UseMvc();
            }
        }
    View Code

    Startup 类的作用:

      1. ConfigureServices方法用于定义(注册)应用程序所使用的服务。(如:ASP.NET Core MVC,Entity Framework Core,Identity 等);

      2. Configure方法用于定义请求管道的中间件,该管道将用于处理应用程序的所有请求。

      3. 注册服务添加方法是无序的,ASP.NET Core在应用程序启动的时候,只要有相应服务即可,而注册中间件时方法是有序的,管道内的每一个组件都可以选择是否将请求交给下一个组件,并在管道中调用下一个组件之前或之后执行某些操作。

    1. ConfigureServices

    应用通过 ConfigureServices 添加服务。 然后,主机和应用服务都可以在 Configure 和整个应用中使用。

    也就是说在 ConfigureServices 中,我们...

    在NETCORE中,依赖注入几乎无处不在,

    未完,待续...下班了,中元节,不该过多加班的。

  • 相关阅读:
    function to_timestamp(timestamp without time zone, unknown) does not exist
    Xshell连接不上Ubuntu解决方式
    怎样使用MobaXterm上传文件到远程Linux系统 MobaXterm怎么使用连接远程服务器?
    notepad++怎样删除空行
    思维脑图在线制作工具网址
    @ApiImplicitParams
    .bat批出处理文件
    主题模型及其在文本情感分析中的应用
    表达式求职JAVA(转)
    2013华为校园招聘java实现(大家水个回复啊)
  • 原文地址:https://www.cnblogs.com/chenwolong/p/Startup.html
Copyright © 2020-2023  润新知