我心中的ASP.NET Core 新核心对象WebHost(一)

以本系列文章向Fish 前辈的那篇 我心中的ASP.NET 核心对象 致敬。(虽然不知道前辈如今在干什么)。一晃就6年过去了,那首  郝云 的《回到那一天》怎么唱来着? 时光一晃,你就三十了。
而咱们都变成了老了的程序员 🙂
 
ASP.NET Core在解开了对windows的依懒以后,整个管线都发生了变化 。这个变化是完全的,原来ASP.NET 中的有些对象直接没有了。被保留下来的,也只是你看起来还差很少,但实现已经彻底不同了。
 
咱们就来讲说我认为的这些ASP.NET Core的这些新的核心对象。
WebHost,  IServiceCollection,IServiceProvider,IApplicationBuilder,IMiddleware 和 RequestDelegate, IServer和IHttpApplication
还有一些一样很重要的对象: ILogger, IConfiguration 

始于WebHost

WebHost像母亲,它承载和孕育了ASP.NET Core下几乎全部的对象,从代码层面入手来看的话能够说是ASP.NET Core的入口,没有它,后面的一切都没有办法开始。固然如何复杂的一项业务,要作好也不容易,WebHost的启动一共分为四阶段。
  • 准备阶段: var builder = new WebHostBuilder(),而后给WebHostBuilder各类填参数
  • 构建阶段: var host = builder.Builder() , 主要负责依懒注入的初始化,以及host的初始化
  • 启动阶段: host.start(); 
  • 运行阶段

program.cs

ASP.NET Core 程序基于一个命令行的程序运行,程序的入口在program.cs的main方法。javascript

public static void Main(string[] args) {
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .Build()
        .Run();
}
WebHost是一个internal类,我相信NETCore团队不但愿你们随意的去new它,而是经过WebHostBuilder去构建。咱们在这里访问的WebHost实际上不是真正的WebHost,真正的WebHost在github的Hosting项目下,命名空间为:Microsoft.AspNetCore.Hosting.Internal。
在ASP.NET Core1x中,咱们必需要本身建立WebHostBuilder。
var host = new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseStartup<Startup>()
                .Build();
这些默认的动做未免有些繁琐,后来到了ASP.NET Core2的时候建立了一个新的项目在github上,叫作MetaPackages 并在  Microsoft.AspNetCore的命名空间下建立了一个static class也就是咱们如今用到的这个,里面主要的方法就是CreateDefaultBuilder。

CreateDefaultBuilder方法

这个方法负责返回给咱们一个WebHostBuilder, 而且调用了如下扩展方法:php

  • UseKestrel 使用kestrel server来处理请求
  • UseContentRoot 设置站点目录 
  • ConfigureAppConfiguration
  • ConfigureLogging
其实和咱们在1X的时候本身构建是一个道理,而这些都是基于WebHostBuilder 的扩展方法它们来自于其它几个不一样的组件。

UseKestrel

WebHost负责托管ASP.NET Core,可是它并不真正从服务器网卡上监听端口以及将网络字节转换到.net core的管道。这些由IServer来处理。css

这里先简单了解一下这个过程,咱们后面会在IServer的环节再详述。咱们这里使用的UseKestrel 来自于github上的项目 KestrelHttpServer。html

里面的Kestrel项目下有一个WebHostBuilderKestrelExtensions类。里面就是这个 UseKestrel扩展方法的定义:java

public static IWebHostBuilder UseKestrel( this IWebHostBuilder hostBuilder) {
    return hostBuilder.ConfigureServices(services =>
    {
    // Don't override an already-configured transport
    services.TryAddSingleton<
        ITransportFactory, 
        SocketTransportFactory>();

    services.AddTransient<
        IConfigureOptions<KestrelServerOptions>, 
        KestrelServerOptionsSetup>();

    services.AddSingleton<
        IServer, 
        KestrelServer>();
    });
}

其实也很简单,都是在进行Server依赖的配置,由于最终的执行都由WebHost来展控。因此WebHost大量依赖的其它外部组件都被定义成接口放到了HttpAbstractions里面,而后由外部扩展方法(多以Use开头,进行配置)git

ASP.NET Core源码里面大量使用扩展方法进行Servier DI的配置,扩展方法定义在各类不一样的命名空间以及项目下。若是不习惯或者不了解相关的部分会以为有些痛苦。程序员

ConfigureAppConfiguration

这个方法专门用来为 WebHostBuilder添加配置,包括appsettings.json的、命令行参数以及环境变量。关于配置这一节咱们留在后面具体来说。github

config.AddJsonFile(
        "appsettings.json", 
        optional: true, 
        reloadOnChange: true)
.AddJsonFile(
    $"appsettings.{env.EnvironmentName}.json", 
     optional: true, 
     reloadOnChange: true);

config.AddEnvironmentVariables();
config.AddCommandLine(args);

ConfigureLogging

logging也是 ASP.NET Core内置组件中的很重要一个,这个方法在默认已经为咱们添加了appsettings中的logging配置以及控制台log。关于日志这一节咱们留在后面具体来说。web

logging.AddConfiguration(
        hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();

UseStartup<>

Startup.cs这个类主要作两件事情的配置Service DI和http管道,这些都是在WebHost启动以前就须要肯定下来的。而UseStartup就是将咱们定义的Startup.cs和 IStartup绑定起来,让WebHost能够找获得。 怎么绑定呢? 固然仍是依赖注入:json

if (typeof(IStartup)
     .GetTypeInfo()
     .IsAssignableFrom(startupType.GetTypeInfo()))
{
    services.AddSingleton(typeof(IStartup), startupType);
}
else
{
    services.AddSingleton(typeof(IStartup), sp =>
    {
    var hostingEnvironment = 
    sp.GetRequiredService<IHostingEnvironment>();

    return new ConventionBasedStartup(
    StartupLoader.LoadMethods(
         sp, 
         startupType, 
         hostingEnvironment.EnvironmentName));
    });
}

VS为咱们添加的Startup.cs默认不继续IStartup接口,因此是采用Convention的这种方式,固然咱们也能够继承IStartup则直接注册成单例到应用程序。

以上是整个 WebHostBuilder的准备阶段,即往里面放了不少的参数。下一篇咱们将接着讲Builder阶段,给了你那么多,你要开始制造点什么东西给我了。

本文首发于公众号jessetalk,转载请保留公众号二维码。

分类: 技术随笔

6 条评论

zhang · 2017年11月25日 下午1:06

支持

fei · 2017年11月25日 下午1:07

评论加邮箱是否有些多余

码农阿宇 · 2017年12月14日 下午10:06

感谢腾飞写了这么好的文章,已经转发并注明了来源而且保留了公众号二维码 谢谢

Chain · 2017年12月29日 上午9:19

已学习。

Allen · 2018年2月27日 下午2:37

感谢

Jay · 2018年7月16日 下午6:13

支持,感谢

发表评论

电子邮件地址不会被公开。 必填项已用*标注

相关文章
相关标签/搜索