.NET Core 3.0 之初识Host源码

写在前面

ASP .NET Core中的通用主机构建器是在v2.1中引入的,应用在启动时构建主机,主机作为一个对象用于封装应用资源以及应用程序启动和生存期管理。其主要功能包括配置初始化(包括加载配置以及配置转换为通用的键值对格式),创建托管环境和Host通用上下文、依赖注入等。

在.NET Core 3.0中采用了IHostBuilder用于创建Host,同时也不再建议使用Web主机,而建议使用泛型主机,主要原因是原有的通用主机仅适用于非HTTP负载,为了提供更加广泛的主机方案,需要将HTTP管道与Web主机的接口分离出来。但Web主机仍会向后兼容。

.NET Core 3.0中创建通用主机

以下代码是V3.0中提供的模板代码,可以看到在创建主机的过程中,已经摒弃了WebHostBuilder的创建方式

   1:  public class Program
   2:  {
   3:      public static void Main(string[] args)
   4:      {
   5:          CreateHostBuilder(args).Build().Run();
   6:      }
   7:   
   8:      public static IHostBuilder CreateHostBuilder(string[] args) =>
   9:          Host.CreateDefaultBuilder(args)
  10:              .ConfigureWebHostDefaults(webBuilder =>
  11:              {
  12:                  webBuilder.UseStartup<Startup>();
  13:              });
  14:  }

而在.NET Core 2.X中

   1:  public class Program
   2:  {
   3:     public static void Main(string[] args)
   4:     {
   5:        CreateWebHostBuilder(args).Build().Run();
   6:     } 
   7:   
   8:     public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
   9:        WebHost.CreateDefaultBuilder(args)
  10:           .UseStartup<Startup>();
  11:  }

V3.0模板中提供的CreateHostBuilder()方法看起来非常类似于V2.X中的CreateWebHostBuilder()。

其主要区别在于对WebHost.CreateDefaultBuilder()由Host.CreateDefaultBuilder()替换。使用CreateDefaultBuilder()辅助方法可以非常轻松地从v2.x切换到v3.0。

另一个区别是关于ConfigureWebHostDefaults()的调用。由于新的主机构建器是通用主机构建器,因此我们必须让它知道我们打算为Web主机配置默认设置。这些默认配置我们可以在ConfigureWebHostDefaults()方法中实现

CreateDefaultBuilder

该方法Microsoft.Extensions.Hosting.Host中,它是一个静态类,里面有两个方法,一个有参的CreateDefaultBuilder(string[] args),一个是无参的。

无参方法源码如下,

   1:  public static IHostBuilder CreateDefaultBuilder() =>
   2:              CreateDefaultBuilder(args: null);

可以看到该方法实际上是设置了默认值。

IHostBuilder CreateDefaultBuilder(string[] args)方法主要有以下功能:

创建HostBuilder对象

   1:  var builder = new HostBuilder();

指定Host要使用的内容根目录

   1:  builder.UseContentRoot(Directory.GetCurrentDirectory());

配置初始化(环境变量、appsettings.json、User Secrets)

   1:  builder.ConfigureHostConfiguration(config =>
   2:  {
   3:      config.AddEnvironmentVariables(prefix: "DOTNET_");
   4:      if (args != null)
   5:      {
   6:          config.AddCommandLine(args);
   7:      }
   8:  });
   9:   
  10:  builder.ConfigureAppConfiguration((hostingContext, config) =>
  11:  {
  12:      var env = hostingContext.HostingEnvironment;
  13:   
  14:      config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
  15:            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
  16:   
  17:      if (env.IsDevelopment() && !string.IsNullOrEmpty(env.ApplicationName))
  18:      {
  19:          var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
  20:          if (appAssembly != null)
  21:          {
  22:              config.AddUserSecrets(appAssembly, optional: true);
  23:          }
  24:      }
  25:   
  26:      config.AddEnvironmentVariables();
  27:   
  28:      if (args != null)
  29:      {
  30:          config.AddCommandLine(args);
  31:      }
  32:  })

日志

   1:  .ConfigureLogging((hostingContext, logging) =>
   2:  {
   3:      logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
   4:      logging.AddConsole();
   5:      logging.AddDebug();
   6:      logging.AddEventSourceLogger();
   7:  })

在开发环境模式下启用作用域验证

   1:  .UseDefaultServiceProvider((context, options) =>
   2:  {
   3:      var isDevelopment = context.HostingEnvironment.IsDevelopment();
   4:      options.ValidateScopes = isDevelopment;
   5:      options.ValidateOnBuild = isDevelopment;
   6:  });

Build

Build()方法是Microsoft.Extensions.Hosting中,并且该方法只会执行一次,当然这种一次只是在同一个实例里面

   1:  public IHost Build()
   2:  {
   3:      if (_hostBuilt)
   4:      {
   5:          throw new InvalidOperationException("Build can only be called once.");
   6:      }
   7:      _hostBuilt = true;
   8:   
   9:      BuildHostConfiguration();
  10:      CreateHostingEnvironment();
  11:      CreateHostBuilderContext();
  12:      BuildAppConfiguration();
  13:      CreateServiceProvider();
  14:   
  15:      return _appServices.GetRequiredService<IHost>();
  16:  }

该方法主要是包括以下功能:

创建HostingEnvironment

创建HostBuilderContext

配置初始化及格式标准化

DI(创建IHostEnvironment、IHostApplicationLifetime、IHostLifetime、IHost)

Run

Run方法运行应用程序并阻止调用线程,直到主机关闭

   1:  public static void Run(this IHost host)
   2:  {
   3:      host.RunAsync().GetAwaiter().GetResult();
   4:  }

以下是RunAsync的源码,此处可以通过设置CancellationToken的值,使应用程序自动关闭

   1:  public static async Task RunAsync(this IHost host, CancellationToken token = default)
   2:  {
   3:      try
   4:      {
   5:          await host.StartAsync(token);
   6:   
   7:          await host.WaitForShutdownAsync(token);
   8:      }
   9:      finally
  10:      {
  11:  #if DISPOSE_ASYNC
  12:          if (host is IAsyncDisposable asyncDisposable)
  13:          {
  14:              await asyncDisposable.DisposeAsync();
  15:          }
  16:          else
  17:  #endif
  18:          {
  19:              host.Dispose();
  20:          }
  21:   
  22:      }
  23:  }

原文地址:https://www.cnblogs.com/edison0621/p/11025310.html

时间: 2024-08-28 00:14:54

.NET Core 3.0 之初识Host源码的相关文章

RxJava1.0 flatMap方法的源码分析

RxJava1.0 flatMap方法的源码分析 package com.yue.test; import java.awt.Cursor; import java.util.ArrayList; import java.util.List; import com.yue.bean.Course; import com.yue.bean.Student; import rx.Observable; import rx.Subscription; import rx.Observable.OnSu

Retrofit2.0使用PC蛋蛋源码搭建姊妹篇——带进度下载文件

Retrofit是PC蛋蛋源码搭建 dsluntan.com 目前最主流的网络框架了,它对网络请求几近完美的封装,大大降低了我们开发者的研发难度,缩短了研发周期.最近项目中遇到了下载视频和图片文件的需求(还有上传视频和图片的需求,请移步这篇博客),我第一反应是用retrofit做呀,so easy!产品接着说,要带下载进度条哦!我一想,retrofit好像并没有给我们提供显示下载进度的接口,哎呀,看来还是得自己个儿整整喽!接下来,我把自己实现Retrofit带进度下载文件的流程分享给大家.在de

初识jQuery源码

为了深入学习下jQuery,最近打算看看源码,刚开始看这个我内心其实是拒绝的...第一印象就是好难理解,没办法硬骨头总是要去啃得,看了好多分析源码的文章博客,第一篇当然是Aaron的jQuery源码解读系列的开篇之整体架构.介绍的还是比较详细的,推荐~当然要抱着怀疑的眼光去看,不一定人家写的就是对的,敲出来验证下才是王道,这篇文章后的评论也可以看看,是大家对于该文章某些地方的质疑. 看完这篇文章其实我是半懂的状态,后来又看到一篇总结的博文,大概是在此基础上总结的. 点这里 我并不想重复的记录下相

centos 7 下 rabbitmq 3.8.0 &amp; erlang 22.1 源码编译安装

centos 7 下 rabbitmq 3.8.0 & erlang 22.1 源码编译安装 安装前请检查好erlang和rabbitmq版本是否相匹配参考:RabbitMQ Erlang Version Requirements 1. erlang 22.1 源码编译安装 1.1 安装Erlang编译安装必要依赖 sudo yum install -y gcc gcc-c++ glibc-devel make ncurses-devel openssl-devel autoconf java-

Android 7.0 Gallery图库源码分析1 - 初识Gallery源码

分析一个项目的源代码时,第一件事就是查看清单文件,找到程序入口,我们从Gallery2源码的清单文件中可以看到GalleryActivity是此应用的启动Activity. 1 <activity android:name="com.android.gallery3d.app.GalleryActivity" android:label="@string/app_name" 2 android:configChanges="keyboardHidde

CoreCLR Host源码分析(C++)

废话不多说,直接上源码: 1.在托管程序集里面执行方法 HRESULT CorHost2::ExecuteAssembly(DWORD dwAppDomainId,//通过CreateAppDomainWithManager创造的domainid LPCWSTR pwzAssemblyPath,//要托管的.net core DLL 路径 int argc, //传递进来参数个数 LPCWSTR* argv,//传递进来参数数组 DWORD *pReturnValue)//指示函数执行的结果标记

Visual C++ 6.0/VC6.0经典插件之源码窗口管理(Visual Booster )插件 安装图解

Visual Booster 是Visual C++ 6.0开发环境的辅助工具,使用该工具打开.cpp..h或者其他资源文件时会在左边及下边显示打开的窗口(并以后缀归类),查看源码的时候相当有用. 1.下载 Visual Booster  Visual Booster 下载地址:http://pan.baidu.com/s/1o6BTbV8 密码:vikq 2.安装 Visual Booster  下载之后解压文件,运行文件夹内的 "Visual Booster.exe" 进行安装.如

EventBus3.0 组件通信框架源码学习总结

一.初始化 EventBus的初始化虽然用了单例模式,但是构造方法居然是public修饰符,可能是应对项目中的多线操作. //单例模式,针对并发情况进行了双层判断 public static EventBus getDefault() { if (defaultInstance == null) { synchronized (EventBus.class) { if (defaultInstance == null) { defaultInstance = new EventBus(); }

OPC2.0服务器开发包源码 opc服务器源代码 server 源程序DLL

1,vc++6.0软件完整工程 2,opc da2.0 服务器开发包,没有任何限制,例子提供1024个点的演示过程 3,opc核心封装成dll库,提供库源码 4,提供调用opc库的测试程序,演示如果用vc6调用dll的全部过程 5,opc服务器模拟数据项,让用户懂得如何开发自己的opc服务器 6,提供测试客户端,可学习和研究opc服务器的建立过程 7,完美的opc服务器开发包,适合开发自己的opc服务器,简单易用.