中间件工厂通过实现IMiddlewareFactory接口,允许自定义中间件创建逻辑,解决传统UseMiddleware无法处理非DI参数、复杂依赖解析和生命周期控制的问题。

在ASP.NET Core中,中间件工厂(Middleware Factory)本质上是一个负责创建和管理中间件实例的机制。它允许你对中间件的实例化过程拥有更精细的控制,尤其是在常规的
app.UseMiddleware<T>
当我们谈论ASP.NET Core的中间件时,最常见的做法莫过于直接调用
app.UseMiddleware<MyMiddleware>()
MyMiddleware
ILogger
DbContext
然而,这种“约定大于配置”的便利性在某些特定场景下会遇到瓶颈。比如,你的中间件构造函数需要一个
string
string
IMiddlewareFactory
IMiddlewareFactory
Create(Type middlewareType)
Release(IMiddleware middleware)
IMiddlewareFactory
Create
IServiceProvider
IMiddlewareFactory
Create
Release
通过这种方式,
IMiddlewareFactory
UseMiddleware<T>
说实话,我第一次接触到中间件工厂这个概念时,觉得它有点“高级”,因为大部分时候
UseMiddleware<T>
它主要解决了以下几个痛点:
IOptions<T>
UseMiddleware<T>
Create
Create
IServiceProvider
RequestDelegate next
Create
Release
InvokeAsync
context.RequestServices
InvokeAsync
context.RequestServices.GetService<T>()
InvokeAsync
在我看来,它更像是一种“逃生舱”,当常规的DI机制无法满足你的特殊中间件需求时,它提供了一个强大且灵活的备用方案。
实现和注册一个自定义的中间件工厂需要几个步骤。我们将通过一个具体的例子来展示,假设我们有一个中间件
MyCustomMiddleware
IMyService
1. 定义服务接口和实现: 首先,我们定义一个简单的服务,用于演示DI。
public interface IMyService
{
string GetData();
}
public class MyService : IMyService
{
private readonly Guid _instanceId = Guid.NewGuid(); // 用于观察实例生命周期
public string GetData() => $"Data from MyService (Instance: {_instanceId})";
}2. 定义自定义中间件: 这个中间件会接收
IMyService
string
RequestDelegate next
next
InvokeAsync
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
public class MyCustomMiddleware : IMiddleware
{
private readonly IMyService _myService;
private readonly string _message;
// 构造函数只接受需要注入的服务,以及工厂提供的自定义参数
public MyCustomMiddleware(IMyService myService, string message)
{
_myService = myService;
_message = message;
}
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
await context.Response.WriteAsync($"Middleware Message: {_message}\n");
await context.Response.WriteAsync($"Service Data: {_myService.GetData()}\n");
await next(context); // 调用管道中的下一个中间件
}
}3. 实现 IMiddlewareFactory
MyCustomMiddleware
using Microsoft.AspNetCore.Http;
using System;
using Microsoft.Extensions.DependencyInjection; // 用于 GetRequiredService
public class MyCustomMiddlewareFactory : IMiddlewareFactory
{
private readonly IServiceProvider _serviceProvider;
public MyCustomMiddlewareFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public IMiddleware Create(Type middlewareType)
{
if (middlewareType == typeof(MyCustomMiddleware))
{
// 从DI容器中解析 IMyService
var myService = _serviceProvider.GetRequiredService<IMyService>();
// 创建 MyCustomMiddleware 实例,并传入自定义的字符串参数
return new MyCustomMiddleware(myService, "Hello from custom factory!");
}
// 对于其他中间件类型,如果这个工厂不负责创建,可以返回 null
// 这样框架会尝试使用其他已注册的工厂或默认机制来创建。
return null;
}
public void Release(IMiddleware middleware)
{
// 如果中间件实现了 IDisposable 接口,可以在这里进行资源释放
(middleware as IDisposable)?.Dispose();
}
}4. 在 Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// 注册我们的服务
services.AddTransient<IMyService, MyService>();
// 注册自定义的中间件工厂
// 注意:IMiddlewareFactory 通常注册为单例。
// 如果你注册了自定义的 IMiddlewareFactory,它会优先于框架默认的工厂。
// 你的工厂需要能处理你希望它处理的中间件类型,或者返回 null 让框架回退到默认行为。
services.AddSingleton<IMiddlewareFactory, MyCustomMiddlewareFactory>();
// 这里不需要注册 MyCustomMiddleware 本身,因为它是由工厂创建的。
// 如果 MyCustomMiddleware 有其他构造函数,并且你想让 DI 容器处理,那才需要注册。
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// ... 其他中间件 ...
// 使用 UseMiddleware<T> 来引用我们的中间件。
// 框架会发现我们注册了 MyCustomMiddlewareFactory,
// 进而调用它的 Create 方法来创建 MyCustomMiddleware 实例。
app.UseMiddleware<MyCustomMiddleware>();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Hello from endpoint!\n");
});
});
}
}运行这个应用,当你访问根路径时,你会看到
MyCustomMiddleware
IMyService
中间件工厂和传统的
app.UseMiddleware<T>()
传统 app.UseMiddleware<T>()
app.UseMiddleware<T>()
T
T
RequestDelegate next
RequestDelegate
T
RequestDelegate next
以上就是ASP.NET Core中的中间件工厂是什么?如何使用?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号