IMiddlewareFactory/IMiddleware 是中间件激活的扩展点。

UseMiddleware 扩展方法检查中间件的已注册类型是否实现 IMiddleware。 如果是,则使用在容器中注册的 IMiddlewareFactory 实例来解析 IMiddleware 实现,而不使用基于约定的中间件激活逻辑。 中间件在应用的服务容器中注册为作用域或瞬态服务。

优点:

  • 按客户端请求(作用域服务的注入)激活
  • 让中间件强类型化

IMiddleware 按客户端请求(连接)激活,因此作用域服务可以注入到中间件的构造函数中。

IMiddleware

IMiddleware 定义应用的请求管道的中间件。 InvokeAsync(HttpContext, RequestDelegate) 方法处理请求,并返回代表中间件执行的 Task。

使用约定激活的中间件:

public class ConventionalMiddleware
{
private readonly RequestDelegate _next; public ConventionalMiddleware(RequestDelegate next)
{
_next = next;
} public async Task InvokeAsync(HttpContext context, AppDbContext db)
{
var keyValue = context.Request.Query["key"]; if (!string.IsNullOrWhiteSpace(keyValue))
{
db.Add(new Request()
{
DT = DateTime.UtcNow,
MiddlewareActivation = "ConventionalMiddleware",
Value = keyValue
}); await db.SaveChangesAsync();
} await _next(context);
}
}

使用 MiddlewareFactory 激活的中间件:

public class FactoryActivatedMiddleware : IMiddleware
{
private readonly AppDbContext _db; public FactoryActivatedMiddleware(AppDbContext db)
{
_db = db;
} public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
var keyValue = context.Request.Query["key"]; if (!string.IsNullOrWhiteSpace(keyValue))
{
_db.Add(new Request()
{
DT = DateTime.UtcNow,
MiddlewareActivation = "FactoryActivatedMiddleware",
Value = keyValue
}); await _db.SaveChangesAsync();
} await next(context);
}
}

程序会为中间件创建扩展:

public static class MiddlewareExtensions
{
public static IApplicationBuilder UseConventionalMiddleware(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<ConventionalMiddleware>();
} public static IApplicationBuilder UseFactoryActivatedMiddleware(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<FactoryActivatedMiddleware>();
}
}

无法通过 UseMiddleware 将对象传递给工厂激活的中间件:

public static IApplicationBuilder UseFactoryActivatedMiddleware(
this IApplicationBuilder builder, bool option)
{
// Passing 'option' as an argument throws a NotSupportedException at runtime.
return builder.UseMiddleware<FactoryActivatedMiddleware>(option);
}

将工厂激活的中间件添加到 Startup.ConfigureServices 的内置容器中:

public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDbContext>(options =>
options.UseInMemoryDatabase("InMemoryDb")); services.AddTransient<FactoryActivatedMiddleware>(); services.AddRazorPages();
}

两个中间件均在 Startup.Configure 的请求处理管道中注册:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
} app.UseConventionalMiddleware();
app.UseFactoryActivatedMiddleware(); app.UseStaticFiles();
app.UseRouting(); app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}

IMiddlewareFactory

IMiddlewareFactory 提供中间件的创建方法。 中间件工厂实现在容器中注册为作用域服务。

可在 Microsoft.AspNetCore.Http 包中找到默认的 IMiddlewareFactory 实现(即 MiddlewareFactory)。

ASP.NET Core 中基于工厂的中间件激活的更多相关文章

  1. ASP.NET Core 中的那些认证中间件及一些重要知识点

    前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...

  2. [转]ASP.NET Core 中的那些认证中间件及一些重要知识点

    本文转自:http://www.qingruanit.net/c_all/article_6645.html 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系 ...

  3. 在ASP.NET Core中编写合格的中间件

    这篇文章探讨了让不同的请求去使用不同的中间件,那么我们应该如何配置ASP.NET Core中间件?其实中间件只是在ASP.NET Core中处理Web请求的管道.所有ASP.NET Core应用程序至 ...

  4. ASP.NET Core 中基于 API Key 对私有 Web API 进行保护

    这两天遇到一个应用场景,需要对内网调用的部分 web api 进行安全保护,只允许请求头账户包含指定 key 的客户端进行调用.在网上找到一篇英文博文 ASP.NET Core - Protect y ...

  5. [译]在Asp.Net Core 中使用外部登陆(google、微博...)

    原文出自Rui Figueiredo的博文<External Login Providers in ASP.NET Core> 摘要:本文主要介绍了使用外部登陆提供程序登陆的流程,以及身份 ...

  6. ASP.NET Core中如果Response.HasStarted已经为true,就不能更改Response.Cookies和Response.Headers等属性的值了

    最近我在ASP.NET Core中做了一个中间件CustomizedMiddleware,要说该中间件的功能也很简单,其实就是往HttpResponse中添加一个Cookie而已,但是我将添加Cook ...

  7. 【译】在Asp.Net Core 中使用外部登陆(google、微博...)

    原文出自Rui Figueiredo的博文<External Login Providers in ASP.NET Core> (本文很长) 摘要:本文主要介绍了使用外部登陆提供程序登陆的 ...

  8. 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获

    项目开发中的一些注意事项以及技巧总结   1.jquery采用ajax向后端请求时,MVC框架并不能返回View的数据,也就是一般我们使用View().PartialView()等,只能返回json以 ...

  9. C# 嵌入dll 动软代码生成器基础使用 系统缓存全解析 .NET开发中的事务处理大比拼 C#之数据类型学习 【基于EF Core的Code First模式的DotNetCore快速开发框架】完成对DB First代码生成的支持 基于EF Core的Code First模式的DotNetCore快速开发框架 【懒人有道】在asp.net core中实现程序集注入

    C# 嵌入dll   在很多时候我们在生成C#exe文件时,如果在工程里调用了dll文件时,那么如果不加以处理的话在生成的exe文件运行时需要连同这个dll一起转移,相比于一个单独干净的exe,这种形 ...

随机推荐

  1. Python 导入模块的两种方法:import xxx 和from...import xxx

    import 方式导入模块 import tool.getsum.add # 导入模块,优先会从启动文件的当前目录开始寻找 # 如果找到,就使用 # 如果找不到,会在系统模块存放目录去 tool.ge ...

  2. EDI模拟实验

    EDI模拟实验 [实验目的] ⑴.了解EDI报文的格式和特点. ⑵.掌握EDI报文生成和发送流程. [实验条件] ⑴.个人计算机一台,预装Windows XP操作系统和浏览器 ⑵.计算机通过局域网形式 ...

  3. js读取xml,javascript读取XML

    IE下示例代码: var xmlDoc = "<root><AlleyWay><Code>1103</Code><Name>胡同2 ...

  4. python 虚拟环境安装

    windows虚拟环境的搭建 安装 # 建议使用pip3安装到python3环境下 pip3 install virtualenv pip3 install virtualenvwrapper-win ...

  5. linux centos8 安装dokcker并启动coreapi

    粘的个人笔记,格式有点乱.勿在意 core api程序包 发布直接部署包: 链接:https://pan.baidu.com/s/1zZe9H1Fevf7DdzfF-MJb9w 提取码:t0ai 源码 ...

  6. Mybatis项目搭建

    MyBatis是一个优秀的持久层框架.原生的jdbc操作存在大量的重复性代码(如注册驱动,创建连接,创建statement,结果集检测等).框架的作用就是把这些繁琐的代码封装. MyBatis通过XM ...

  7. asp.net core的授权过滤器中获取action上的Attribute

    var action = context.ActionDescriptor as ControllerActionDescriptor; var permission = action.MethodI ...

  8. javascript中的描述对象(Descriptor)

    对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为.Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象. 获取对象中属性描述对象 Ob ...

  9. quart动态执行定时任务

    今天有个需求,前端可以将定时任务自定义保存到数据库,每天根据查询数据库来执行任务. 其实不用动态也是可以实现,但是.也是想试试动态执行定时任务看看怎么样的. (1)建立一个QuartzManage类 ...

  10. day76:luffy:项目前端环境搭建&轮播图的实现

    目录 1.项目前端环境搭建 1.创建项目目录 2.前端初始化全局变量和全局方法 3.跨域CORS 4.axios配置 2.轮播图功能的实现 1.安装依赖模块 2.上传文件相关配置 3.注册home子应 ...