ASP.Net Core -- Web Host的默认配置

默认配置

1:使用kestrel web server

  •  这是ASP.Net Core内置的,是跨平台的,凡是ASP.Net Core所支持的平台,Kestrel都能在其运行,Kestrel Web Server就可以监听HTTP请求,当然,也可以在命令行来运行Kestrel Web Server

打开Program.cs文件,查看如下代码:

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

我们可以对CreateWebHostBuilder进行反编译,查看源码,可以看到以下代码:

webHostBuilder.UseKestrel(delegate (WebHostBuilderContext builderContext, KestrelServerOptions options)
{
    options.Configure(builderContext.Configuration.GetSection("Kestrel"));
})

可以看到,hostbuilder.UserKestrel(),使用的就是Kestrel服务。

2:使用IIS集成

使用的两个方法:第一个是UserIIS(),第二个是UseIISIntergration()

3:Log,用户打印日志文件

可以打印在控制台,也可以打印在debug窗口,等等

4:IConfiguration接口

默认的WebHostBuilder会创建一个对象,这个对象将实现IConfiguration这个接口,我们可以在整个ASP.Net Core的Web应用里来访问这个对象,我们可以通过这个IConfiguration这个接口,从这个接口对象里获取一些我们所需要的配置信息

继续对CreateWebHostBuilder进行反编译,如下:

WebHostBuilder webHostBuilder = new WebHostBuilder();

在CreateDefaultBuilder里有一行:WebHostBuilder hostBuilder = new WebHostBuilder();我们可以再对WebHostBuilder进行反编译,然后进入到如下:

private IConfiguration _config;

        private WebHostOptions _options;

        private WebHostBuilderContext _context;

        private bool _webHostBuilt;

        private List<Action<WebHostBuilderContext, IConfigurationBuilder>> _configureAppConfigurationBuilderDelegates;

        
        public WebHostBuilder()
        {
            _hostingEnvironment = new HostingEnvironment();
            _configureServicesDelegates = new List<Action<WebHostBuilderContext, IServiceCollection>>();
            _configureAppConfigurationBuilderDelegates = new List<Action<WebHostBuilderContext, IConfigurationBuilder>>();
            _config = new ConfigurationBuilder().AddEnvironmentVariables("ASPNETCORE_").Build();
            if (string.IsNullOrEmpty(GetSetting(WebHostDefaults.EnvironmentKey)))
            {
                UseSetting(WebHostDefaults.EnvironmentKey, Environment.GetEnvironmentVariable("Hosting:Environment") ?? Environment.GetEnvironmentVariable("ASPNET_ENV"));
            }

            if (string.IsNullOrEmpty(GetSetting(WebHostDefaults.ServerUrlsKey)))
            {
                UseSetting(WebHostDefaults.ServerUrlsKey, Environment.GetEnvironmentVariable("ASPNETCORE_SERVER.URLS"));
            }

            _context = new WebHostBuilderContext
            {
                Configuration = _config
            };
        }

我们可以看到,里边有个属性,类型为IConfiguration,最后在构造函数数里,又把_config给了Configuration,我们再对那个IConfiguration属性类型进行反编译,看到如下:

public interface IConfiguration
    {
        //
        // 摘要:
        //     Gets or sets a configuration value.
        //
        // 参数:
        //   key:
        //     The configuration key.
        //
        // 返回结果:
        //     The configuration value.
        string this[string key]
        {
            get;
            set;
        }

        //
        // 摘要:
        //     Gets a configuration sub-section with the specified key.
        //
        // 参数:
        //   key:
        //     The key of the configuration section.
        //
        // 返回结果:
        //     The Microsoft.Extensions.Configuration.IConfigurationSection.
        //
        // 言论:
        //     This method will never return null. If no matching sub-section is found with
        //     the specified key, an empty Microsoft.Extensions.Configuration.IConfigurationSection
        //     will be returned.
        IConfigurationSection GetSection(string key);

        //
        // 摘要:
        //     Gets the immediate descendant configuration sub-sections.
        //
        // 返回结果:
        //     The configuration sub-sections.
        IEnumerable<IConfigurationSection> GetChildren();

        //
        // 摘要:
        //     Returns a Microsoft.Extensions.Primitives.IChangeToken that can be used to observe
        //     when this configuration is reloaded.
        //
        // 返回结果:
        //     A Microsoft.Extensions.Primitives.IChangeToken.
        IChangeToken GetReloadToken();
    }

这个里边比较简单,我们可以看到有个Key,就是以key对应value的形式,获取字符串的值。下边我们说一下主要从哪些地方获取可以获取的配置信息,也就是可以通过IConfiguration获取的配置信息都从哪里来

IConfiguration配置信息来源

1:appsettings.json

2:User Secrets

3:环境变量

4:命令行参数

首先就是找到appsettings.json这个文件,这个文件是默认的,也就是在项目中的根目录下如果有这个文件,就会直接找到这个文件,我们再对CreateWebHostBuilder进行反编译,看一下为啥为默认找到appserttings.json这个文件,如下:

IHostingEnvironment hostingEnvironment = hostingContext.HostingEnvironment;
                config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).AddJsonFile("appsettings." + hostingEnvironment.EnvironmentName + ".json", optional: true, reloadOnChange: true);
                if (hostingEnvironment.IsDevelopment())
                {
                    Assembly assembly = Assembly.Load(new AssemblyName(hostingEnvironment.ApplicationName));
                    if (assembly != null)
                    {
                        config.AddUserSecrets(assembly, optional: true);
                    }
                }

                config.AddEnvironmentVariables();
                if (args != null)
                {
                    config.AddCommandLine(args);
                }

可以看到,直接给出了,就是appsetting.josn这个文件名,另外,还可以根据环境变量的不同来找到环境变量指定的json文件。。

来看一下项目中默认的appsetting.json文件,如下:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
}

里边已经有一些默认配置了。目前项目启动会直接打印hello world,而这个hello world是直接写死的,如下:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }

现在,要做些小小的改动,目的很简单,就只是为了测试使用IConfiguration来获取appsettings.json文件里的信息,现在我要把这个hello  world做成活的,写在appsettings.json文件里,然后在startup.cs文件里用IConfiguration来获取,再输出hello world。

先修改appsettings.json文件,如下:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Welcome": "Hello World"
}

再修改startup.cs文件,如下:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IConfiguration configuration)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.Run(async (context) =>
            {
                var welcome = configuration["Welcome"];
                await context.Response.WriteAsync(welcome);
            });
        }

这样,启动项目,依旧会输出hello world,而这个hello world就来自appsettings.json文件里。为什么可以在configure里直接使用IConfiguration,因为asp.net core里使用的都是依赖注入,不仅这里可以使用,其它地方也都可以使用。

看源码,不仅有appsettings.json,还有其它的可以访问,现在测试一下它们访问优先级是怎么样的:

我们可以在系统环境里添加一个变量,也叫Welcome,值也叫hello world!(这里就不上图了,不想改系统............)当启动项目时,输出的值的是系统环境里的welcome,而不是appsettings.json文件里的welcome,这就说明,系统环境变量后加载的,因为这样,系统环境变量里的值会把appsettings.json文件里welcome的值覆盖掉,这就好比在程序中,我们写一个int a=10;接着又写了a=20;最终输出的是20,我们可以再对CreateDefaultBuilder进行反编译,看源码就清除了:

IHostingEnvironment hostingEnvironment = hostingContext.HostingEnvironment;
                config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).AddJsonFile("appsettings." + hostingEnvironment.EnvironmentName + ".json", optional: true, reloadOnChange: true);
                if (hostingEnvironment.IsDevelopment())
                {
                    Assembly assembly = Assembly.Load(new AssemblyName(hostingEnvironment.ApplicationName));
                    if (assembly != null)
                    {
                        config.AddUserSecrets(assembly, optional: true);
                    }
                }

                config.AddEnvironmentVariables();
                if (args != null)
                {
                    config.AddCommandLine(args);
                }

我们可以看到,如果三个文件都存在的话,先找appsettings.json文件,再找开发环境变量,最后才是系统环境变量,所以如果三个文件里都有welcome这个变量的时候,最后一个系统环境变量的值会把前边两个的welcome的都覆盖掉。当然,最后还有个命令行参数环境变量,这是最后一个,如果这四个都有的话,最后输出的一定是命令行里的welcome,会把前三个都覆盖掉。

先简单学习一下,以后再修改!

posted @ 2020-02-02 15:00  初晨~  阅读(615)  评论(0编辑  收藏  举报