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. 「Redis」字符串

    原文链接:https://www.changxuan.top/?p=1109 简介 Redis 中自定义的字符串结构. 字符串是 Redis 中最常用的一种数据类型,在 Redis 中专门封装了一个字 ...

  2. 跨时代的MySQL8.0新特性解读

    目录 MySQL发展历程 MySQL8.0新特性 秒级加列 性能提升 文档数据库 SQL增强 共用表表达式(CTEs) 不可见索引(Invisible Indexes) 降序索引(Descending ...

  3. C# 软件开机启动

    如果需要查看更多文章,请微信搜索公众号 csharp编程大全,需要进C#交流群群请加微信z438679770,备注进群, 我邀请你进群! ! !---------------------------- ...

  4. 吐血分享一款免费看所有付费影视的app,不好用来石欠我

    前言 朋友经常找我要各种付费影视资源,在下逛遍各大网站,终于找到一款app,那简直是神器啊. 几乎各大主流平台的付费影视都能观看,亲测有效.还在浏览器一个一个搜资源而费劲?? 还在为只买了一个平台的V ...

  5. Java 移位运算、符号位扩展

    类型取值范围 short 是1字节,即8位.而且 Java 中只有有符号数,所以最大值 0111,1111=2^7-1. 同时计算机中以补码形式存负数,所以可以多表示一个数,则最小值 1000,000 ...

  6. openstack 高可用环境部署(8节点)(一)

  7. 例题4-2 刽子手游戏(Hangman Judge, UVa 489)

    #include<stdio.h> #include<string.h> int ok ,no; int left ,chance; char s[20] ,s2[20]; v ...

  8. 生物信息-McScan(Python-jcvi)共线性画图

    比较基因组学中,共线性的分析的图无疑是最漂亮的. 共线性分析可以很好地解释进化关系和多倍化事件. 本文主要介绍的是唐老师的Python版McScan(jcvi工具包),这个包很强大,但是其功能在官网的 ...

  9. Windows Server 设置自动登陆

    前言 Windows Server 相信很多人都在使用,但是系统每次登陆都比较麻烦,能否设置自动登陆呢?有兴趣一起来学习一下吧!的自动登陆方法也比较多,在此分享一个实用简单的,通过命令来设置" ...

  10. Nginx禁止html等缓存

    +++ date="2020-10-16" title="Nginx禁止html等缓存" tags=["nginx"] categories ...