向LocalDevelopmentImpersonation中间件传递IConfiguration遇构造函数错误求助
问题解决:中间件构造函数无法定位的错误
错误原因
你的LocalDevelopmentImpersonation中间件实现了IMiddleware接口,ASP.NET Core会通过依赖注入(DI)容器实例化这类中间件,而非直接使用UseMiddleware传递的参数。当前代码存在两个核心问题:
- 构造函数依赖
RequestDelegate,但该类型并非DI容器默认注册的服务,无法被自动解析。 - 扩展方法中通过
Options.Create(configuration)传递的是IOptions<IConfiguration>类型,与构造函数所需的IConfiguration参数类型不匹配,导致DI无法找到匹配的构造函数。
解决方案
方案1:改用基于约定的中间件(推荐,实现更简洁)
移除IMiddleware接口实现,改用ASP.NET Core约定式中间件模式:
修改后的中间件类
namespace LocalDevelopmentImpersonation { public sealed class LocalDevelopmentImpersonation { private readonly RequestDelegate _next; private readonly SafeAccessTokenHandle _safeAccessTokenHandle; private readonly bool _isLocal; public LocalDevelopmentImpersonation(RequestDelegate next, IConfiguration configuration) { _safeAccessTokenHandle = LocalDevelopmentImpersonationSetup.GetSafeAccessTokenHandle(out var receivedSafeAccessTokenSuccessfully); _next = next; _isLocal = LocalDevelopmentImpersonationSetup.IsLocal(receivedSafeAccessTokenSuccessfully, configuration); } public async Task InvokeAsync(HttpContext context) { if (_isLocal) { await WindowsIdentity.RunImpersonated(_safeAccessTokenHandle, async () => { await _next(context); }); } else { await _next(context); } } } }
修改后的扩展方法
namespace LocalDevelopmentImpersonation.ExtensionMethods { public static class LocalDevelopmentImpersonationExtensions { public static IApplicationBuilder UseLocalDevelopmentImpersonation(this IApplicationBuilder app) { return app.UseMiddleware<LocalDevelopmentImpersonation>(); } public static IApplicationBuilder UseLocalDevelopmentImpersonation(this IApplicationBuilder app, IConfiguration configuration) { if (app == null) throw new ArgumentNullException(nameof(app)); if (configuration == null) throw new ArgumentNullException(nameof(configuration)); return app.UseMiddleware<LocalDevelopmentImpersonation>(configuration); } } }
调用代码保持不变即可,约定式中间件会自动将UseMiddleware传递的参数注入构造函数。
方案2:保留IMiddleware接口
如果坚持使用IMiddleware,需调整构造函数并注册中间件到DI容器:
修改后的中间件类
namespace LocalDevelopmentImpersonation { public sealed class LocalDevelopmentImpersonation : IMiddleware { private readonly SafeAccessTokenHandle _safeAccessTokenHandle; private readonly bool _isLocal; // IMiddleware的InvokeAsync会自动接收RequestDelegate,构造函数无需依赖它 public LocalDevelopmentImpersonation(IConfiguration configuration) { _safeAccessTokenHandle = LocalDevelopmentImpersonationSetup.GetSafeAccessTokenHandle(out var receivedSafeAccessTokenSuccessfully); _isLocal = LocalDevelopmentImpersonationSetup.IsLocal(receivedSafeAccessTokenSuccessfully, configuration); } public async Task InvokeAsync(HttpContext context, RequestDelegate next) { if (_isLocal) { await WindowsIdentity.RunImpersonated(_safeAccessTokenHandle, async () => { await next(context); }); } else { await next(context); } } } }
注册中间件到DI容器
在Program.cs中添加:
builder.Services.AddTransient<LocalDevelopmentImpersonation>();
简化扩展方法
namespace LocalDevelopmentImpersonation.ExtensionMethods { public static class LocalDevelopmentImpersonationExtensions { public static IApplicationBuilder UseLocalDevelopmentImpersonation(this IApplicationBuilder app) { return app.UseMiddleware<LocalDevelopmentImpersonation>(); } } }
修改调用代码
var app = builder.Build(); app.UseLocalDevelopmentImpersonation();
此时DI会自动注入IConfiguration(默认已注册),无需手动传递。
内容的提问来源于stack exchange,提问作者Aaron C
相关产品推荐
相关产品推荐

