ASP.NET Core 中基于工厂的中间件激活Factory-based middleware activation in ASP.NET Core

本文内容

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

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

优点:

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

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

查看或下载示例代码如何下载

IMiddlewareIMiddleware

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

使用约定激活的中间件:

  1. public class ConventionalMiddleware
  2. {
  3. private readonly RequestDelegate _next;
  4. public ConventionalMiddleware(RequestDelegate next)
  5. {
  6. _next = next;
  7. }
  8. public async Task InvokeAsync(HttpContext context, AppDbContext db)
  9. {
  10. var keyValue = context.Request.Query["key"];
  11. if (!string.IsNullOrWhiteSpace(keyValue))
  12. {
  13. db.Add(new Request()
  14. {
  15. DT = DateTime.UtcNow,
  16. MiddlewareActivation = "ConventionalMiddleware",
  17. Value = keyValue
  18. });
  19. await db.SaveChangesAsync();
  20. }
  21. await _next(context);
  22. }
  23. }

使用 MiddlewareFactory 激活的中间件:

  1. public class FactoryActivatedMiddleware : IMiddleware
  2. {
  3. private readonly AppDbContext _db;
  4. public FactoryActivatedMiddleware(AppDbContext db)
  5. {
  6. _db = db;
  7. }
  8. public async Task InvokeAsync(HttpContext context, RequestDelegate next)
  9. {
  10. var keyValue = context.Request.Query["key"];
  11. if (!string.IsNullOrWhiteSpace(keyValue))
  12. {
  13. _db.Add(new Request()
  14. {
  15. DT = DateTime.UtcNow,
  16. MiddlewareActivation = "FactoryActivatedMiddleware",
  17. Value = keyValue
  18. });
  19. await _db.SaveChangesAsync();
  20. }
  21. await next(context);
  22. }
  23. }

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

  1. public static class MiddlewareExtensions
  2. {
  3. public static IApplicationBuilder UseConventionalMiddleware(
  4. this IApplicationBuilder builder)
  5. {
  6. return builder.UseMiddleware<ConventionalMiddleware>();
  7. }
  8. public static IApplicationBuilder UseFactoryActivatedMiddleware(
  9. this IApplicationBuilder builder)
  10. {
  11. return builder.UseMiddleware<FactoryActivatedMiddleware>();
  12. }
  13. }

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

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

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

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddDbContext<AppDbContext>(options =>
  4. options.UseInMemoryDatabase("InMemoryDb"));
  5. services.AddTransient<FactoryActivatedMiddleware>();
  6. services.AddRazorPages();
  7. }

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

  1. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  2. {
  3. if (env.IsDevelopment())
  4. {
  5. app.UseDeveloperExceptionPage();
  6. }
  7. else
  8. {
  9. app.UseExceptionHandler("/Error");
  10. }
  11. app.UseConventionalMiddleware();
  12. app.UseFactoryActivatedMiddleware();
  13. app.UseStaticFiles();
  14. app.UseRouting();
  15. app.UseEndpoints(endpoints =>
  16. {
  17. endpoints.MapRazorPages();
  18. });
  19. }

IMiddlewareFactoryIMiddlewareFactory

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

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

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

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

优点:

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

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

查看或下载示例代码如何下载

IMiddlewareIMiddleware

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

使用约定激活的中间件:

  1. public class ConventionalMiddleware
  2. {
  3. private readonly RequestDelegate _next;
  4. public ConventionalMiddleware(RequestDelegate next)
  5. {
  6. _next = next;
  7. }
  8. public async Task InvokeAsync(HttpContext context, AppDbContext db)
  9. {
  10. var keyValue = context.Request.Query["key"];
  11. if (!string.IsNullOrWhiteSpace(keyValue))
  12. {
  13. db.Add(new Request()
  14. {
  15. DT = DateTime.UtcNow,
  16. MiddlewareActivation = "ConventionalMiddleware",
  17. Value = keyValue
  18. });
  19. await db.SaveChangesAsync();
  20. }
  21. await _next(context);
  22. }
  23. }

使用 MiddlewareFactory 激活的中间件:

  1. public class FactoryActivatedMiddleware : IMiddleware
  2. {
  3. private readonly AppDbContext _db;
  4. public FactoryActivatedMiddleware(AppDbContext db)
  5. {
  6. _db = db;
  7. }
  8. public async Task InvokeAsync(HttpContext context, RequestDelegate next)
  9. {
  10. var keyValue = context.Request.Query["key"];
  11. if (!string.IsNullOrWhiteSpace(keyValue))
  12. {
  13. _db.Add(new Request()
  14. {
  15. DT = DateTime.UtcNow,
  16. MiddlewareActivation = "FactoryActivatedMiddleware",
  17. Value = keyValue
  18. });
  19. await _db.SaveChangesAsync();
  20. }
  21. await next(context);
  22. }
  23. }

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

  1. public static class MiddlewareExtensions
  2. {
  3. public static IApplicationBuilder UseConventionalMiddleware(
  4. this IApplicationBuilder builder)
  5. {
  6. return builder.UseMiddleware<ConventionalMiddleware>();
  7. }
  8. public static IApplicationBuilder UseFactoryActivatedMiddleware(
  9. this IApplicationBuilder builder)
  10. {
  11. return builder.UseMiddleware<FactoryActivatedMiddleware>();
  12. }
  13. }

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

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

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

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddDbContext<AppDbContext>(options =>
  4. options.UseInMemoryDatabase("InMemoryDb"));
  5. services.AddTransient<FactoryActivatedMiddleware>();
  6. services.AddMvc()
  7. .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
  8. }

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

  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  2. {
  3. if (env.IsDevelopment())
  4. {
  5. app.UseDeveloperExceptionPage();
  6. app.UseDatabaseErrorPage();
  7. }
  8. else
  9. {
  10. app.UseExceptionHandler("/Error");
  11. }
  12. app.UseConventionalMiddleware();
  13. app.UseFactoryActivatedMiddleware();
  14. app.UseStaticFiles();
  15. app.UseMvc();
  16. }

IMiddlewareFactoryIMiddlewareFactory

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

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

其他资源Additional resources