ASP.NET Core系列:中间件

1. 概述

  ASP.NET Core中的中间件是嵌入到应用管道中用于处理请求和响应的一段代码。

2. 使用 IApplicationBuilder 创建中间件管道

2.1 匿名函数

  使用Run, Map, Use ,MapWhen等扩展方法来实现。

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    }
}

  第一个Run委托终止了管道。

  用 Use 将多个请求委托链接在一起。 next 参数表示管道中的下一个委托。 可通过不 调用 next 参数使管道短路。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.Use(async (context, next) =>
    {
        context.Response.ContentType = "text/plain;charset=utf-8";

        await context.Response.WriteAsync("进入第一个委托 执行下一个委托之前\r\n");

        // 调用管道中的下一个委托
        await next.Invoke();

        await context.Response.WriteAsync("结束第一个委托 执行下一个委托之后\r\n");
    });

    app.Run(async context =>
    {
        await context.Response.WriteAsync("进入第二个委托\r\n");

        await context.Response.WriteAsync("Hello World!\r\n");

        await context.Response.WriteAsync("结束第二个委托\r\n");
    });
}

2.2 自定义中间件类

  新建中间件类:MyMiddleware.cs

using Microsoft.AspNetCore.Http;

public class MyMiddleware
{
    private readonly RequestDelegate _next;

    // 在应用程序的生命周期中,中间件的构造函数只会被调用一次
    public MyMiddleware(RequestDelegate next)
    {
        this._next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        await context.Response.WriteAsync("Hello World!");

        await _next(context);
    }
}

  将自定义中间件配置到请求处理管道中,Startup.cs文件调整:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseMiddleware<MyMiddleware>();
}

  将中间件MyMiddleware改成扩展方法:

  新建扩展类MyMiddlewareExtension.cs

using Microsoft.AspNetCore.Builder;

public static class MyMiddlewareExtension
{
    public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder)
    {
        // 使用UseMiddleware将自定义中间件添加到请求处理管道中
        return builder.UseMiddleware<MyMiddleware>();
    }
}

  将自定义中间件配置到请求处理管道中,Startup.cs文件调整:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseMyMiddleware();
}

2.3 自定义中间件类传入初始参数

public class GreetingOption
{
    public string At { get; set; }

    public string To { get; set; }
}
using Microsoft.AspNetCore.Http;

public class GreetingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly GreetingOption _option;

    public GreetingMiddleware(RequestDelegate next, GreetingOption option)
    {
        _next = next;
        _option = option;
    }

    public async Task Invoke(HttpContext context)
    {
        var message = $"Good {_option.At} {_option.To}";
        await context.Response.WriteAsync(message);
    }
}
using Microsoft.AspNetCore.Builder;

public static class GreetingMiddlewareExtension
{
    public static IApplicationBuilder UseGreetingMiddleware(this IApplicationBuilder app, GreetingOption option)
    {
        return app.UseMiddleware<GreetingMiddleware>(option);
    }
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseGreetingMiddleware(new GreetingOption
    {
        At = "Morning",
        To = "Libing"
    });
}

3. IMiddleware

  IMiddleware提供了强类型约束的中间件,其默认实现是MiddlewareFactory,接口定义如下:

public interface IMiddleware
{
    Task InvokeAsync(HttpContext context, RequestDelegate next);
}

  IMiddlewareFactory用于创建IMiddleware实例及对实例进行回收,接口定义:

public interface IMiddlewareFactory
{
    public IMiddleware Create (Type middlewareType);
    
    public void Release (IMiddleware middleware);
}

3.1 自定义IMiddleware类型中间件

  修改MyMiddleware,实现IMiddleware接口:

using Microsoft.AspNetCore.Http;

public class MyMiddleware : IMiddleware
{
    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        await context.Response.WriteAsync("Hello World!");

        await next(context);
    }
}

  将自定义中间件配置到请求处理管道中,Startup.cs文件调整:

public void ConfigureServices(IServiceCollection services)
{
    // 在服务容器中注册自定义中间件
    services.AddSingleton<MyMiddleware>();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // 使用 UseMiddleware() 把自定义中间件添加到管道中
    app.UseMyMiddleware();
}
posted @ 2019-08-19 17:18 libingql 阅读(...) 评论(...) 编辑 收藏