ASP.NET Core中的中间件依赖注入指的是在中间件组件内部获取并使用依赖注入容器管理的服务实例的能力,借助这个特性,我们可以把中间件需要的业务逻辑、数据访问等依赖通过容器自动注入,避免硬编码依赖,让中间件的逻辑更清晰、更易测试。

中间件依赖注入的核心原理
ASP.NET Core的依赖注入容器会在应用启动时构建服务树,中间件本身是在应用配置阶段通过UseMiddleware方法注册的,容器会负责解析中间件的构造函数参数以及中间件的Invoke或InvokeAsync方法的参数,自动注入匹配类型的服务实例。
实现方式一:基于构造函数注入
这是最常用的中间件依赖注入方式,适合中间件需要依赖的服务在整个中间件生命周期内都需要使用的情况。
步骤1:定义需要注入的服务接口和实现
首先我们定义一个简单的日志服务,后续会把这个服务注入到中间件中:
// 日志服务接口
public interface ICustomLogger
{
void Log(string message);
}
// 日志服务实现
public class ConsoleLogger : ICustomLogger
{
public void Log(string message)
{
Console.WriteLine($"[日志]{message}");
}
}
步骤2:创建支持构造函数注入的中间件类
中间件类需要包含构造函数,参数就是需要注入的服务类型,同时必须包含一个Invoke或InvokeAsync方法,这个方法接收HttpContext作为参数,还可以额外接收其他由容器注入的服务:
public class CustomMiddleware
{
private readonly RequestDelegate _next;
private readonly ICustomLogger _logger;
// 构造函数注入ICustomLogger服务
public CustomMiddleware(RequestDelegate next, ICustomLogger logger)
{
_next = next;
_logger = logger;
}
// Invoke方法处理请求,HttpContext是必须的参数
public async Task InvokeAsync(HttpContext context)
{
_logger.Log($"请求路径:{context.Request.Path}");
await _next(context);
_logger.Log($"响应状态码:{context.Response.StatusCode}");
}
}
步骤3:注册服务和中间件
在Program.cs中先注册日志服务,再通过UseMiddleware注册自定义中间件:
var builder = WebApplication.CreateBuilder(args);
// 注册日志服务到依赖注入容器,生命周期设为瞬态
builder.Services.AddTransient<ICustomLogger, ConsoleLogger>();
var app = builder.Build();
// 注册自定义中间件
app.UseMiddleware<CustomMiddleware>();
app.MapGet("/", () => "Hello World!");
app.Run();
实现方式二:基于Invoke方法参数注入
如果中间件只需要某个服务处理单次请求时使用,不需要在构造函数中持有依赖,可以直接把服务作为Invoke方法的参数,容器会自动解析这个参数并注入实例。
修改上面的中间件类,去掉构造函数的服务注入,把ICustomLogger放到InvokeAsync方法的参数中:
public class CustomMiddleware
{
private readonly RequestDelegate _next;
public CustomMiddleware(RequestDelegate next)
{
_next = next;
}
// 直接在InvokeAsync参数中注入ICustomLogger,不需要在构造函数中声明
public async Task InvokeAsync(HttpContext context, ICustomLogger logger)
{
logger.Log($"请求路径:{context.Request.Path}");
await _next(context);
logger.Log($"响应状态码:{context.Response.StatusCode}");
}
}
这种方式的优势是服务的生命周期和请求生命周期绑定,不需要中间件长期持有服务实例,适合轻量级的临时依赖场景。
注意事项
- 中间件的构造函数参数只能由依赖注入容器解析,不能传递自定义参数,如果需要自定义参数,可以通过中间件扩展方法实现。
- 如果中间件同时使用了构造函数注入和Invoke方法参数注入,两种方式的注入服务可以共存,不会互相冲突。
- 注入的服务生命周期需要匹配使用场景,比如如果中间件是单例的,不要注入作用域级别的服务,否则会引发生命周期不匹配的异常。
适用场景
中间件依赖注入适合以下场景:需要在中间件中实现日志记录、请求鉴权、参数校验、请求耗时统计等功能,这些功能对应的服务可以通过依赖注入统一管理和注入,避免中间件和业务逻辑强耦合。
ASP.NET_Core中间件依赖注入IServiceProvider修改时间:2026-06-25 07:33:24