.NET 6 Minimal APIs:将自定义Middleware的Func逻辑移至类后如何依赖注入?
解决方案
方案一:创建实例化的认证处理类(推荐)
不要用静态类,而是创建一个依赖注入友好的实例类,通过构造函数注入所需服务,再将逻辑封装到实例方法中,这样既解耦又能正常使用DI。
1. 编写认证处理类
public class AuthenticationHandler { private readonly AuthenticationService _authService; // 构造函数注入依赖的AuthenticationService public AuthenticationHandler(AuthenticationService authService) { _authService = authService; } // 方法签名严格匹配原lambda的Func类型 public async Task<(bool Pass, Error Error)> Validate(HttpRequest request, Identity accessibility, Message message, /* 其他参数 */) { // 直接使用注入的_authService处理业务逻辑 var isValid = await _authService.CheckAccess(accessibility, message); if (!isValid) { return (false, new Error("认证失败")); } // 其他业务逻辑... return (true, null); } }
2. 注册处理类并修改Program.cs
在Program.cs中注册这个处理类,然后在中间件的lambda里通过请求上下文的服务容器获取实例:
builder.Services.AddScoped<AuthenticationService>(); // 注册认证处理类,生命周期和AuthenticationService保持一致(Scoped) builder.Services.AddScoped<AuthenticationHandler>(); var app = builder.Build(); app.UseCustomMiddleware<IContract, Methods>("/", async (request, accessibility, message, ...) => { // 从当前请求的服务容器获取处理类实例(请求级作用域,比根容器更安全) var handler = request.HttpContext.RequestServices.GetRequiredService<AuthenticationHandler>(); return await handler.Validate(request, accessibility, message, ...); });
关键说明
- 为什么不用静态类:静态类无法通过构造函数注入依赖,手动解析服务时容易出现生命周期管理问题(比如Scoped服务用根容器解析会导致实例复用)。
- 为什么用
request.HttpContext.RequestServices:这是当前请求的服务提供者,自带请求级作用域,能正确解析Scoped/Transient类型的服务,比直接用app.Services(根容器)更符合.NET的DI规范。
可选优化:封装lambda逻辑
如果不想在Program.cs里保留lambda,可以再封装一层扩展方法,但前提是你有权修改中间件的扩展类:
public static class CustomMiddlewareExtensions { public static IApplicationBuilder UseCustomAuthenticationMiddleware<TContract, TMethods>(this IApplicationBuilder app, string path) { return app.UseCustomMiddleware<TContract, TMethods>(path, async (request, accessibility, message, ...) => { var handler = request.HttpContext.RequestServices.GetRequiredService<AuthenticationHandler>(); return await handler.Validate(request, accessibility, message, ...); }); } }
之后在Program.cs里直接调用:
app.UseCustomAuthenticationMiddleware<IContract, Methods>("/");
内容的提问来源于stack exchange,提问作者wiki
相关产品推荐
相关产品推荐

