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

来源:互联网 发布:2017淘宝双十一报名 编辑:程序博客网 时间:2024/05/16 18:16

以本系列文章向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方法。

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, 并且调用了以下扩展方法:

  • UseKestrel 使用kestrel server来处理请求

  • UseContentRoot 设置站点目录 

  • ConfigureAppConfiguration

  • ConfigureLogging

其实和我们在1X的时候自己构建是一个道理,而这些都是基于WebHostBuilder 的扩展方法它们来自于其它几个不同的组件。

UseKestrel

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

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

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

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开头,进行配置)

ASP.NET Core源码里面大量使用扩展方法进行Servier DI的配置,扩展方法定义在各种不同的命名空间以及项目下。如果不习惯或者不了解相关的部分会觉得有些痛苦。

ConfigureAppConfiguration

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

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。关于日志这一节我们留在后面具体来讲。

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

UseStartup<>

Startup.cs这个类主要做两件事情的配置Service DI和http管道,这些都是在WebHost启动之前就需要确定下来的。而UseStartup就是将我们定义的Startup.cs和 IStartup绑定起来,让WebHost可以找得到。 怎么绑定呢? 当然还是依赖注入:

 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阶段,给了你那么多,你要开始制造点什么东西给我了

原文地址:http://www.jessetalk.cn/2017/11/11/aspnet-core-object-webhost/


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com


原创粉丝点击