.NET5中 Host.CreateDefaultBuilder(args)详解

首先当我们创建.NET5 Web API 程序的时候,会生成下面这个 Program.cs 文件:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }
 
    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

这个类包含两个方法:MainCreateHostBuilder

通过Host类调用CreateHostBuilder方法返回一个IHostBuilder对象,那么这个主机对象是什么呢?

Host类实现了IHost接口,用途如下:

  • 应用程序配置设置
  • 给应用程序添加依赖注入,配置.NET Core本机容器
  • 配置日志

Host.cs

Host 是一个静态类,包含了两个方法: CreateDefaultBuilder() 、CreateDefaultBuilder (args)

在下面源码中我将会剖析这两个方法的用途:

public static class Host
    {
       public static IHostBuilder CreateDefaultBuilder() =>
            CreateDefaultBuilder(args: null);

        public static IHostBuilder CreateDefaultBuilder(string[] args)
        {
            var builder = new HostBuilder();
 
            builder.UseContentRoot(Directory.GetCurrentDirectory());
            builder.ConfigureHostConfiguration(config =>
            {
                config.AddEnvironmentVariables(prefix: "DOTNET_");
                if (args != null)
                {
                    config.AddCommandLine(args);
                }
            });
 
            builder.ConfigureAppConfiguration((hostingContext, config) =>
            {
                IHostEnvironment env = hostingContext.HostingEnvironment;
 
                bool reloadOnChange = hostingContext.Configuration.GetValue("hostBuilder:reloadConfigOnChange", defaultValue: true);
 
                config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: reloadOnChange)
                      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: reloadOnChange);
 
                if (env.IsDevelopment() && !string.IsNullOrEmpty(env.ApplicationName))
                {
                    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) =>
            {
                bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
 
                if (isWindows)
                {
                   
                    logging.AddFilter<EventLogLoggerProvider>(level => level >= LogLevel.Warning);
                }
 
                logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                logging.AddConsole();
                logging.AddDebug();
                logging.AddEventSourceLogger();
 
                if (isWindows)
                {
                    logging.AddEventLog();
                }
 
                logging.Configure(options =>
                {
                    options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
                                                        | ActivityTrackingOptions.TraceId
                                                        | ActivityTrackingOptions.ParentId;
                });
 
            })
            .UseDefaultServiceProvider((context, options) =>
            {
                bool isDevelopment = context.HostingEnvironment.IsDevelopment();
                options.ValidateScopes = isDevelopment;
                options.ValidateOnBuild = isDevelopment;
            });
 
            return builder;
        }
    }

首先无参的CreateDefaultBuilder()方法只是通过调用传递null值来调用有参的CreateDefaultBuilder(string[] args)方法。

var builder = new HostBuilder(); 

CreateDefaultBuilder(string[] args) 方法从创建HostBuilder 类型对象的实例化开始(继承自IHostBuilder),我们可以直接在这个实例上调用Build.Run()方法来启动我们的ASP.NET 主机,但是只是这样调用的话,并没有对我们的主机以及应用程序做配置,那么怎么配置呢?

Host Configuration(主机配置)

builder.UseContentRoot(Directory.GetCurrentDirectory()); 

这个方法定义了Host 执行的目录,默认是根目录。

应用程序配置(Setting up the app)

builder.ConfigureAppConfiguration((hostingContext, config) =>
{
    IHostEnvironment env = hostingContext.HostingEnvironment;
 
    bool reloadOnChange = hostingContext.Configuration.GetValue("hostBuilder:reloadConfigOnChange", defaultValue: true);
 
    config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: reloadOnChange)
          .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: reloadOnChange);
 
    if (env.IsDevelopment() && !string.IsNullOrEmpty(env.ApplicationName))
    {
        var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
        if (appAssembly != null)
        {
            config.AddUserSecrets(appAssembly, optional: true);
        }
    }
 
    config.AddEnvironmentVariables();
 
    if (args != null)
    {
        config.AddCommandLine(args);
    }
});

hostingContext.HostingEnvironment 表示我们在开发或者生产环境下的环境信息。

bool reloadOnChange = hostingContext.Configuration.GetValue("hostBuilder:reloadConfigOnChange", defaultValue: true);
 
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: reloadOnChange)
      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: reloadOnChange); 

在程序启动配置时,它会加载我们项目中的appsettings.json及其下面的配置json 文件。通过AddJsonFile()这个方法来实现,这个方法有三个入参:

  • Path(string): .json 文件的相对路径位置
  • Optional(bool): 指定文件是否是必须的,如果设置为false,那么如果找不到文件则会抛出文件找不到异常。
  • ReloadOnchange(bool): 如果设置为true,那么我们改变配置文件,那么应用程序也会随之更改而无需重新启动。
bool reloadOnChange = hostingContext.Configuration.GetValue("hostBuilder:reloadConfigOnChange", defaultValue: true);

这段代码是.NET5 新增的,在之前.net core的应用程序中,reloadOnchange的值始终是ture,至此我们就可以对hostBuilder:reloadConfigOnChange 配置为false;

if (env.IsDevelopment() && !string.IsNullOrEmpty(env.ApplicationName)) 
{ 
    var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName)); 
    if (appAssembly != null) 
    { 
        config.AddUserSecrets(appAssembly, optional: true); 
    } 
} 

这段程序的作用是如果我们需要加密我们的appsettings.json文件,则可以使用;用法如下:Safe storage of app secrets in development in ASP.NET Core | Microsoft Docs

配置日志(Logging)

.ConfigureLogging((hostingContext, logging) =>
 {
     bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
 
     // IMPORTANT: This needs to be added *before* configuration is loaded, this lets
     // the defaults be overridden by the configuration.
     if (isWindows)
     {
         // Default the EventLogLoggerProvider to warning or above
         logging.AddFilter<EventLogLoggerProvider>(level => level >= LogLevel.Warning);
     }
 
     logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
     logging.AddConsole();
     logging.AddDebug();
     logging.AddEventSourceLogger();
 
     if (isWindows)
     {
         // Add the EventLogLoggerProvider on windows machines
         logging.AddEventLog();
     }
 
     logging.Configure(options =>
     {
         options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
                                             | ActivityTrackingOptions.TraceId
                                             | ActivityTrackingOptions.ParentId;
     });
 })

 上述代码用来设置应用程序的生成日志;从代码中可以看出如果程序跑在windows环境下,级别是或者高于警告级别的日志将会被输出在控制台,VS输出窗口以及写入系统日志服务。

依赖注入

.UseDefaultServiceProvider((context, options) =>
{
    bool isDevelopment = context.HostingEnvironment.IsDevelopment();
    options.ValidateScopes = isDevelopment;
    options.ValidateOnBuild = isDevelopment;
});

CreateDefaultBuilder 方法的最后一步是将依赖注入添加到我们的应用程序中。UseDefaultServiceProvider这个方法用来添加.NET 5 或者.NET Core自带的IOC容器。


技术交流请加vx:qubiancheng666

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值