netcore 图解及核心概念理解(部分摘录)


图例

image

详细说明:

一、启动顺序

1、程序启动,运行main方法
2、创建web服务器,启动startup类
3、执行ConfigureServices,为程序配置可供重用的服务
4、执行Configure,配置中间件处理请求和响应

二、中间件

什么是中间件

中间件是用于组成应用程序管道来处理请求和响应的组件。管道内的每一个组件都可以选择是否将请求交给下一个组件、并在管道中调用下一个组件之前和之后执行某些操作。请求委托被用来建立请求管道,请求委托处理每一个 HTTP 请求。 请求委托通过使用 IApplicationBuilder 类型的 Run、Map 以及 Use 扩展方法来配置,并在 Startup 类中传给 Configure 方法 。每个单独的请求委托都可以被指定为一个内嵌匿名方法,或其定义在一个可重用的类中。这些可重用的类被称作 中间件 或 中间件组件。每个位于请求管道内的中间件组件负责调用管道中下一个组件,或适时短路调用链。 Migrating HTTP Modules to Middleware 解释了请求管道在 ASP.NET Core 和之前版本之间的区别,并提供了更多中间件样例。

用 IApplicationBuilder 创建中间件管道 ASP.NET 请求管道由一系列的请求委托所构成,它们一个接着一个被调用,如图所示(该执行线程按黑色箭头的顺序执行):

image 每个委托在下一个委托之前和之后都有机会执行操作。任何委托都能选择停止传递到下一个委托,转而自己处理该请求。这被叫做请求管道的短路,而且是一种有意义的设计,因为它可以避免不必要的工作。比方说,一个授权(authorization)中间件只有在通过身份验证之后才调用下一个委托,否则它就会被短路并返回 “Not Authorized” 的响应。异常处理委托需要在管道的早期被调用,这样它们就能够捕捉到发生在管道内更深层次出现的异常了。

Run,Map 与 Use 你可以使用 Run、Map 和 Use 配置 HTTP 管道。Run 方法将会短路管道(因为它不会调用 next 请求委托)。因此,Run 应该只能在你的管道尾部被调用。Run 是一种惯例,有些中间件组件可能会暴露他们自己的 Run[Middleware] 方法,而这些方法只能在管道末尾处运行。下面这两个中间件等价的,其中有用到 Use 的版本没有使用 next 参数:

public void ConfigureEnvironmentOne(IApplicationBuilder app)
{
    app.Run(async context =>//手工高亮
    {
        await context.Response.WriteAsync("Hello from " + _environment);
    });
}

public void ConfigureEnvironmentTwo(IApplicationBuilder app)
{
app.Use(
async (context, next) =>//手工高亮
{
await context.Response.WriteAsync("Hello from " + _environment);
});
}

Map 扩展方法用于匹配基于请求路径的请求委托。Map 只接受路径,并配置单独的中间件管道的功能。在下例中,任何基于路径 /maptest 的请求都会被管道中所配置的 HandleMapTest 方法所处理。

private static void HandleMapTest(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        await context.Response.WriteAsync("Map Test Successful");
    });
}

public void ConfigureMapping(IApplicationBuilder app)
{
app.Map(
"/maptest", HandleMapTest);//手工高亮

}

 

编写中间件

对于更复杂的请求处理功能,推荐在自己的类中实现中间件,并暴露 IApplicationBuilder 扩展方法,这样就能通过 Configure 方法来被调用。之前演示的简易日志中间件就能被转换为一个中间件类(middleware class):只要在其构造函数中获得下一个 RequestDelegate 并提供一个 Invoke方法,如下所示:

image

中间件遵循 显式依赖原则 并在其构造函数中暴露所有依赖项。中间件能够利用到 UseMiddleware 扩展方法的优势,直接通过它们的构造函数注入服务,就像下面的例子所示。依赖注入服务是自动完成填充的,扩展所用到的 params 参数数组被用于非注入参数。

public static class RequestLoggerExtensions
{
    public static IApplicationBuilder UseRequestLogger(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<RequestLoggerMiddleware>();
    }
}

通过使用扩展方法和相关中间件类,Configure 方法变得非常简洁和高可读性。

image

尽管 RequestLoggerMiddleware 在其构造函数中需要 ILoggerFactory 参数,但无论是 Startup 类还是 UseRequestLogger 扩展方法都不需要显式依赖之。相反,它将自动地通过内置的 UseMiddleware<T> 来执行依赖注入以提供之。

测试中间件(通过给 LogMiddleware 设置 Hosting:Environment 环境变量)会输出下图的结果(当时用了 WebListener 时):

 

 注意
UseStaticFiles 扩展方法(该方法会创建 StaticFileMiddleware)同样也使用了 UseMiddleware<T>。所以除了 StaticFileOptions 参数被传入之外,构造函数的其他参数都由 UseMiddleware<T> 和依赖注入所提供。

--


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM