11、WebHost  第六个对象

  到目前为止我们已经知道了由一个服务器和多个中间件构成的管道是如何完整针对请求的监听、接收、处理和最终响应的,接下来来讨论这样的管道是如何被构建出来的。管道是在作为应用宿主的WebHost对象启动的时候被构建出来的,在ASP.NET Core Mini中,我们将表示应用宿主的IWebHost接口简写成如下的形式:只包含一个StartAsync方法用来启动应用程序。

public interface IWebHost
{
Task StartAsync();
}

  由于由WebHost构建的管道由Server和HttpHandler构成,我们在默认实现的WebHost类型中,我们直接提供者两个对象。在实现的StartAsync方法中,我么只需要将后者作为参数调用前者的StartAsync方法将服务器启动就可以了。

public class WebHost : IWebHost
{
private readonly IServer _server;
private readonly RequestDelegate _handler;
public WebHost(IServer server, RequestDelegate handler)
{
_server = server;
_handler = handler;
}
public Task StartAsync() => _server.StartAsync(_handler);
}

12、WebHostBuilder  第七个对象

  作为最后一个着重介绍的核心对象,WebHostBuilder的使命非常明确:就是创建作为应用宿主的WebHost。由于在创建WebHost的时候需要提供注册的服务器由所有注册中间件构建而成的RequestDelegate,所以在对应接口IWebHostBuilder中,我们为它定义了三个核心方法。

public interface IWebHostBuilder
{
IWebHostBuilder UseServer(IServer server);
IWebHostBuilder Configure(Action<IApplicationBuilder> configure);
IWebHost Build();
}

  除了用来创建WebHost的Build方法之外,我们提供了用来注册服务器的UseServer方法和用来注册中间件的Configure方法。Configure方法提供了一个类型为Action<IApplicationBuilder>的参数,意味着我们针对中间件的注册是利用上面介绍的IApplicationBuilder对象来完成的。

  如下所示的WebHostBuilder是针对IWebHostBuilder接口的默认实现,它具有两个字段分别用来保存注册的中间件和调用Configure方法提供的Action<IApplicationBuilder>对象。当Build方法被调用之后,我们创建一个ApplicationBuilder对象(方法内部使用new ApplicationBuilder并添加相关配置),并将它作为参数调用这些Action<IApplicationBuilder>委托,进而将所有中间件全部注册到这个ApplicationBuilder对象上。我们最终调用它的Build方法得到由所有中间件共同构建的RequestDelegate对象,并利用它和注册的服务器构建作为应用宿主的WebHost对象。

public class WebHostBuilder : IWebHostBuilder
{
private IServer _server;
private readonly List<Action<IApplicationBuilder>> _configures = new List<Action<IApplicationBuilder>>(); public IWebHostBuilder Configure(Action<IApplicationBuilder> configure)
{
_configures.Add(configure);
return this;
}
public IWebHostBuilder UseServer(IServer server)
{
_server = server;
return this;
} public IWebHost Build()
{
var builder = new ApplicationBuilder();
foreach (var configure in _configures)
{
configure(builder);
}
return new WebHost(_server, builder.Build());
}
}

13、回顾一下Hello World 2

  到目前为止,我们已经将ASP.NET Core Mini涉及的七个核心对象介绍完了,然后我们再来回顾一下建立在这个模拟框架上的Hello World程序。

public class Program
{
public static async Task Main()
{
await new WebHostBuilder()
.UseHttpListener()
.Configure(app => app
.Use(FooMiddleware)
.Use(BarMiddleware)
.Use(BazMiddleware))
.Build()
.StartAsync();
}
public static RequestDelegate FooMiddleware(RequestDelegate next)
=> async context => {
await context.Response.WriteAsync("Foo=>");
await next(context);
};
public static RequestDelegate BarMiddleware(RequestDelegate next)
=> async context => {
await context.Response.WriteAsync("Bar=>");
await next(context);
};
public static RequestDelegate BazMiddleware(RequestDelegate next)
=> context => context.Response.WriteAsync("Baz");
}

  首选我们调用WebHostBuilder的扩展方法UseHttpListener采用如下的方式完成了针对HttpListenerServer的注册。由于中间件体现为一个Func<RequestDelegate, RequestDelegate>对象,我们自然可以采用与之具有相同声明的方法(FooMiddleware、BarMiddleware和BazMiddleware)来定义对应的中间件。中间件调用HttpResponse的WriteAsync以如下的方式将指定的字符串写入响应主体的输出流。

public static partial class Extensions
{
public static IWebHostBuilder UseHttpListener(this IWebHostBuilder builder, params string[] urls)
=> builder.UseServer(new HttpListenerServer(urls)); public static Task WriteAsync(this HttpResponse response, string contents)
{
var buffer = Encoding.UTF8.GetBytes(contents);
return response.Body.WriteAsync(buffer, , buffer.Length);
}
}

  ASP.NET Core Mini模拟了真实ASP.NET Core框架最核心的部分,即由服务器和中间件构成的请求处理管道。真正的ASP.NET Core框架自然要复杂得多得多,那么我们究竟遗漏了什么呢?

  如上所示的5个部分是ASP.NET Core Mini没有涉及的,其中包括依赖注入、以Startup和StartupFilter的中间件注册方式、针对多种数据源的配置系统、诊断日志系统和一系列预定义的中间件,上述的每个方面都涉及到一个庞大的主题,我们将ASP.NET Core涉及到的方方面都写在我将要出版的《ASP.NET Core框架揭秘》中,如果你想全方面了解一个真实的ASP.NET Core框架,敬请期待新书出版。

ASP.NET Core框架深度学习(四)宿主对象的更多相关文章

  1. ASP.NET Core框架深度学习(一) Hello World

    对于学习Core的框架,对我帮助最大的一篇文章是Artech的<200行代码,7个对象——让你了解ASP.NET Core框架的本质>,最近我又重新阅读了一遍该文.本系列文章就是结合我的阅 ...

  2. ASP.NET Core框架深度学习(二) 管道对象

    4.HttpContext 第一个对象 我们的ASP.NET Core Mini由7个核心对象构建而成.第一个就是大家非常熟悉的HttpContext对象,它可以说是ASP.NET Core应用开发中 ...

  3. ASP.NET Core框架深度学习(三) Server对象

    8.Server   第五个对象 服务器在管道中的职责非常明确,当我们启动应用宿主的WebHost的时候,服务它被自动启动.启动后的服务器会绑定到指定的端口进行请求监听,一旦有请求抵达,服务器会根据该 ...

  4. ASP.NET Core 框架本质学习

    本文作为学习过程中的一个记录. 学习文章地址: https://www.cnblogs.com/artech/p/inside-asp-net-core-framework.html 一. ASP.N ...

  5. C#中的函数式编程:递归与纯函数(二) 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面

    C#中的函数式编程:递归与纯函数(二)   在序言中,我们提到函数式编程的两大特征:无副作用.函数是第一公民.现在,我们先来深入第一个特征:无副作用. 无副作用是通过引用透明(Referential ...

  6. 200行代码,7个对象——让你了解ASP.NET Core框架的本质

    2019年1月19日,微软技术(苏州)俱乐部成立,我受邀在成立大会上作了一个名为<ASP.NET Core框架揭秘>的分享.在此次分享中,我按照ASP.NET Core自身的运行原理和设计 ...

  7. 了解ASP.NET Core框架的本质

    了解ASP.NET Core框架的本质 ASP.NET Core自身的运行原理和设计思想创建了一个 “迷你版” 的ASP.NET Core框架,并且利用这个 “极简” 的模拟框架阐述了ASP.NET ...

  8. 200行代码,7个对象——让你了解ASP.NET Core框架的本质

    原文:200行代码,7个对象--让你了解ASP.NET Core框架的本质 2019年1月19日,微软技术(苏州)俱乐部成立,我受邀在成立大会上作了一个名为<ASP.NET Core框架揭秘&g ...

  9. ASP.NET Core框架的本质

    源文章地址:http://www.cnblogs.com/artech/p/inside-asp-net-core-framework.html 1.从Hello World谈起 当我们最开始学习一门 ...

随机推荐

  1. JavaScript定时器方法

    一.setTimeout() 延迟性操作 window.setTimeout(function(){ console.log('派大星');//延迟了4秒 },4000); console.log(' ...

  2. SpringBoot2.0 整合 JWT 框架,解决Token跨域验证问题

    本文源码:GitHub·点这里 || GitEE·点这里 一.传统Session认证 1.认证过程 1.用户向服务器发送用户名和密码. 2.服务器验证后在当前对话(session)保存相关数据. 3. ...

  3. oracle将时间加一天,加小时,加分,加秒

    前言 oracle 时间类型可以直接相加,但加的是天,以天为单位,我们了解了这个,加一天,一小时,一分,一秒就都简单了. 加一天 select to_date('2019-08-15 22:03:10 ...

  4. 微信小程序之左右布局

    本文以一个简单的小例子,简述在微信小程序开发中左右布局功能的实现方式,主要涉及scroll-view ,列表数据绑定,及简单样式等内容,仅供学习分享使用. 概述 在微信小程序开发中,左右分栏(左边显示 ...

  5. 【重学Git】高级命令篇

    1.分离HEAD.HEAD 总是指向当前分支上最近一次提交记录. 所谓分离HEAD,就是让HEAD直接指向某一条具体的提交记录,而不是默认的通过分支名指向当前分支的最近一条提交记录. 2.相对引用^. ...

  6. Navicat Premium12.0 常用快捷键

  7. 使用NodeJS模块-NodeJS官方提供的核心模块

    除了使用自己写的本地模块以外,NodeJS可以使用另外两种类型的模块,分别是NodeJS官方提供的核心模块和第三方提供的模块 NodeJS官方提供的核心模块 NodeJS平台自带的一套基本的功能模块, ...

  8. OpenCV绘制直线,矩形和园

    首先导入我们所需要的库: import numpy as np import cv2 import matplotlib.pyplot as plt 自定义显示图像的函数: def show(imag ...

  9. msyql master thread

    ------------------------------------------------------ 2015-02-10----------------------------------- ...

  10. docker 网络设置概述

    docker有3种网络: 使用命令docker network ls,执行结果如下. NETWORK ID NAME DRIVER SCOPE 82e8822065c7 bridge bridge l ...