dotNetCore阅读源码-CreateDefaultBuilder及ConfigureWebHostDefaults内部

版本:DotNetCore 3.1

CreateDefaultBuilder内部源码:

 public static IHostBuilder CreateDefaultBuilder(string[] args)
        {
            //实例化
            var builder = new HostBuilder();

            //指定主机要使用的内容根目录。
            builder.UseContentRoot(Directory.GetCurrentDirectory());
           //设置生成器自身的配置
            builder.ConfigureHostConfiguration(config =>
            {
                //环境变量必须以DOTNET_为前缀开头,并且前缀将从环境变量名称中删除。
                //默认配置会加载前缀为 DOTNET_ 和 ASPNETCORE_ 的环境变量和命令行参数。
                //DOTNET_ 和 ASPNETCORE_ 前缀会由 ASP.NET Core 用于主机和应用配置,但不用于用户配置.
                //前缀会在读取配置键值对时被去除。
                config.AddEnvironmentVariables(prefix: "DOTNET_");
                //如果传入的参数不为空
                if (args != null)
                {
                    //将参数添加配置 这里可以执行一些cmd命令
                    //例如发布MVC到IIS,将web.config 内部的
                    //<aspNetCore processPath="dotnet" arguments = ".\MyApp.dll" stdoutLogEnabled = "false" stdoutLogFile = ".\logs\stdout" hostingModel = "inprocess" />
                    //作为参数命令  dotnet  MyApp.dll 执行 
                    config.AddCommandLine(args);
                }
            });

       //为生成过程和应用程序的其余部分设置配置
            builder.ConfigureAppConfiguration((hostingContext, config) =>
            {
                //获取主机环境
                var env = hostingContext.HostingEnvironment;
                //获取appsettings.json    appsettings.xxx.json文件
                //注意如果参数名相同,appsettings.xxx.json会覆盖appsetting.json的参数变量
                config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
                //判断当前是否开发环境及主机环境名不为空
                if (env.IsDevelopment() && !string.IsNullOrEmpty(env.ApplicationName))
                {
                    //加载当前主机环境
                    var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
                    if (appAssembly != null)
                    {
                        //添加用户秘钥
                        //若使用该配置可查看https://docs.microsoft.com/zh-cn/aspnet/core/security/app-secrets?view=aspnetcore-3.1&tabs=windows
                        config.AddUserSecrets(appAssembly, optional: true);
                    }
                }

                //指定环境变量的前缀
                //例如config.AddEnvironmentVariables(prefix: "MyCustomPrefix_");
                //测试:
                //set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
                //set MyCustomPrefix_Position__Title = Editor_with_customPrefix
                //set MyCustomPrefix_Position__Name = Environment_Rick_cp
                //dotnet run
                config.AddEnvironmentVariables();

                if (args != null)
                {   //将参数添加配置 这里可以执行一些cmd命令
                    //例如发布MVC到IIS,将web.config 内部的
                    //<aspNetCore processPath="dotnet" arguments = ".\MyApp.dll" stdoutLogEnabled = "false" stdoutLogFile = ".\logs\stdout" hostingModel = "inprocess" />
                    //作为参数命令执行  dotnet  MyApp.dll
                    config.AddCommandLine(args);
                }
            })
            .ConfigureLogging((hostingContext, logging) =>
            {
                //默认日志
                var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);

                //重要提示:
                //这需要在配置被加载之前被添加,
                //这使得默认值将被配置覆盖。
                if (isWindows)
                {
                    //将EventLogLoggerProvider的默认值设置为警告或更高
                    logging.AddFilter<EventLogLoggerProvider>(level => level >= LogLevel.Warning);
                }
                //获取appsettings.json 或者appsettings.xxx.json文件内的Logging参数
                logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                //添加控制台打印
                logging.AddConsole();
                //添加Debug的调试记录器。
                logging.AddDebug();
                //添加事件源记录器
                logging.AddEventSourceLogger();

                if (isWindows)
                {
                    // 在Windows机器上添加EventLogLoggerProvider
                    logging.AddEventLog();
                }
            })
            .UseDefaultServiceProvider((context, options) =>
            {
                //作用域验证
                //如果应用环境为开发,则将ValidateScopes 设为 true。
                var isDevelopment = context.HostingEnvironment.IsDevelopment();
                //ValidateScopes执行检查以验证范围内的服务永远不会从根提供程序解析,则为 true;否则为 false。 默认为 false。
                options.ValidateScopes = isDevelopment;
                //若要执行检查,验证是否可在 BuildServiceProvider(IServiceCollection, ServiceProviderOptions) 调用期间创建所有服务,是则为 true;
                //否则为 false。 默认为 false。 注意:此检查不会验证开放式泛型服务。
                options.ValidateOnBuild = isDevelopment;
            });

            return builder;
        }

 

ConfigureWebHostDefaults内部源码:

 

   public static IHostBuilder ConfigureWebHostDefaults(this IHostBuilder builder, Action<IWebHostBuilder> configure)
        {
           
            return builder.ConfigureWebHost(webHostBuilder =>
            {
                //2.1版本之前的调用方式
                //注意这是webhost不是host
                WebHost.ConfigureWebDefaults(webHostBuilder);

                configure(webHostBuilder);
            });
        }

        ///以下默认值应用于IWebHostBuilder:
        ///使用Kestrel作为网络服务器,并使用应用程序的配置提供程序对其进行配置,
        ///添加HostFiltering中间件,
        ///如果ASPNETCORE_FORWARDEDHEADERS_ENABLED = true,则添加ForwardedHeaders中间件,
        ///并启用IIS集成。
        internal static void ConfigureWebDefaults(IWebHostBuilder builder)
        {
            builder.ConfigureAppConfiguration((ctx, cb) =>
            {
                if (ctx.HostingEnvironment.IsDevelopment())
                {
                    StaticWebAssetsLoader.UseStaticWebAssets(ctx.HostingEnvironment, ctx.Configuration);
                }
            });
            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[] { "*" });
                    }
                });
                // 变更通知
                services.AddSingleton<IOptionsChangeTokenSource<HostFilteringOptions>>(
                            new ConfigurationChangeTokenSource<HostFilteringOptions>(hostingContext.Configuration));

                services.AddTransient<IStartupFilter, HostFilteringStartupFilter>();
                // 如果ASPNETCORE_FORWARDEDHEADERS_ENABLED = true,则添加ForwardedHeaders中间件,
                if (string.Equals("true", hostingContext.Configuration["ForwardedHeaders_Enabled"], StringComparison.OrdinalIgnoreCase))
                {
                    services.Configure<ForwardedHeadersOptions>(options =>
                    {
                        options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
                        //默认情况下仅允许使用环回代理。 清除该限制,因为转发器是
                        //通过显式配置启用。
                        options.KnownNetworks.Clear();
                        options.KnownProxies.Clear();
                    });

                    services.AddTransient<IStartupFilter, ForwardedHeadersStartupFilter>();
                }
                //添加路由服务
                services.AddRouting();
            })

            //在IIS发布的时候需要AspNetCoreModule
            //配置在AspNetCoreModule后面运行时服务器应侦听的端口和基本路径。
            //该应用程序还将配置为捕获启动错误。
            .UseIIS()
            .UseIISIntegration();//启用IIS集成。
        }

 

posted @ 2020-07-08 10:20  流星泪  阅读(1949)  评论(2编辑  收藏  举报