zoukankan      html  css  js  c++  java
  • Asp.Net Core 入门(一)——Program.cs做了什么

      ASP.NET Core 是微软推出的一种全新的跨平台开源 .NET 框架,用于在 Windows、Mac 或 Linux 上生成基于云的新式 Web 应用程序。国内目前关于Asp.Net Core的书比较少,自己靠着阅读微软官方文档,源码和在52ABP梁老师的教程中慢慢的在一点点的积累Asp.Net Core的知识。因此希望将自己的学习记录下来,以此巩固和交流。

      闲话不多说,我们知道学习一门新的技术,最好的方法就是从它的启动入口进行跟踪,那么接下来我们先来看下Asp.Net Core的入口文件Program.cs。

      笔者使用的.Net SDK 是 2.2版本,所以下面的介绍都是基于2.2版本的。

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

      我们看到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;
            }
     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();
            }

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

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

      2、配置日志记录

      3、设置Web服务器

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

      现在我们来看一下Asp.Net Core是如何加载配置的。

      访问配置信息可以通过 IConfiguration 接口进行访问,我们从源码也可以看到,Asp.Net Core加载配置的过程,它们之间是按照顺序如果有相同的配置会依次被覆盖:appsettings.json,appsettings{Environment}.json(应用程序配置文件) -->User Secrets(用户机密) --> Environment Variables(环境变量) --> Command-line arguments(命令行参数)。

      其中应用程序配置文件的{Environment}可以在项目的属性中调试进行配置,如果项目中不存在单独为某个环境配置的,采用appsettings.json。

      应用程序配置文件我们比较清楚,以前在.Net Framework我们有web.config,但是Asp.Net Core中出现了User Secrets用户机密,那么它有什么用呢,其实它可以保存我们比较敏感的配置信息,比如第三方的Key,像微信的Appkey之类的。那我们该如何添加User Secrets呢?我们需要在命令行的窗口下,切换到我们项目的执行文件夹下,即bin所在的那层目录,运行命令dotnet user-secrets set [KeyName] [KeyValue]

      接着我们就可以在VS项目中查看到该用户机密了

      

      Environment variables(环境变量)在 Properties文件夹下的launchSettings.json进行配置

    {
      "iisSettings": {
        "windowsAuthentication": false,
        "anonymousAuthentication": true,
        "iisExpress": {
          "applicationUrl": "http://localhost:4084",
          "sslPort": 44338
        }
      },
      "profiles": {
        "IIS Express": {
          "commandName": "IISExpress",
          "launchBrowser": true,
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development"
          }
        },
        "StudentManagement": {
          "commandName": "Project",
          "launchBrowser": true,
          "applicationUrl": "https://localhost:5001;http://localhost:5000",
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development"
          }
        }
      }
    }

      这里的profiles可以在VS调试运行的时候做选择

      而Command-line arguments(命令行参数)需要结合命令行窗口执行: dotnet run KeyName="KeyValue"。

      那么我们怎么获取配置信息呢? Asp.Net Core提供了ConfigureAppConfiguration 可以给我们调用获取配置,在StartUp文件中可以使用 _configuration["KeyName"] 来获取。

       最后,我们再看一下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。

      现在我们知道了CreateDefaultBuilder做了什么工作了,那么在它之后调用了UseStartup<Startup>(),那Startup做了什么工作呢,我们下篇再来讨论。

      

  • 相关阅读:
    Persist Security Info=False是干什么的
    SQL Server windows身份验证和SQL Server身份验证的连接字符串
    SQL Server windows身份验证和SQL Server身份验证的连接字符串
    Entity Framework—配置文件设置
    Entity Framework—配置文件设置
    inner outer
    group by
    SQL Select语句完整的执行顺序(转)
    with check(转)
    三层和MVC
  • 原文地址:https://www.cnblogs.com/jesen1315/p/11038385.html
Copyright © 2011-2022 走看看