.NET 7中如何在Program.cs引用的静态类中使用依赖注入?
最佳解决思路
方案1:利用OIDC事件上下文获取依赖(推荐)
OIDC的事件参数(如RemoteFailureContext、AuthorizationCodeReceivedContext)自带HttpContext,而HttpContext.RequestServices就是当前请求的DI容器。你可以直接在事件处理方法中通过它获取配置或非静态的AuthenticationHelper实例,无需提前构建服务提供者,也不会出现单例重复创建的问题。
示例代码:
// Program.cs 中配置OIDC builder.Services.AddAuthentication() .AddOpenIdConnect(options => { // 其他OIDC配置项... options.Events = new OpenIdConnectEvents { OnRemoteFailure = context => { // 从上下文获取AuthenticationHelper实例 var authHelper = context.HttpContext.RequestServices.GetRequiredService<AuthenticationHelper>(); return authHelper.HandleRemoteFailure(context); }, OnAuthorizationCodeReceived = context => { var authHelper = context.HttpContext.RequestServices.GetRequiredService<AuthenticationHelper>(); return authHelper.HandleAuthorizationCodeReceived(context); } }; }); // 注册非静态的AuthenticationHelper为单例 builder.Services.AddSingleton<AuthenticationHelper>();
在AuthenticationHelper中直接注入IConfiguration:
public class AuthenticationHelper { private readonly IConfiguration _configuration; public AuthenticationHelper(IConfiguration configuration) { _configuration = configuration; } public async Task HandleRemoteFailure(RemoteFailureContext context) { // 使用_configuration读取配置项 var clientId = _configuration["OpenIdConnect:ClientId"]; // 你的业务处理逻辑... await Task.CompletedTask; } public async Task HandleAuthorizationCodeReceived(AuthorizationCodeReceivedContext context) { // 同理使用配置完成逻辑 await Task.CompletedTask; } }
这个方案完全符合.NET的DI设计原则,没有额外的容器创建问题,是最规范的实现方式。
方案2:直接读取配置文件(适合简单场景)
如果不想依赖DI,也可以在静态类中手动构建配置实例,直接读取配置文件:
public static class AuthenticationHelper { private static readonly IConfiguration _configuration; static AuthenticationHelper() { _configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .AddEnvironmentVariables() .Build(); } public static async Task HandleRemoteFailure(RemoteFailureContext context) { var clientId = _configuration["OpenIdConnect:ClientId"]; // 你的业务处理逻辑... await Task.CompletedTask; } }
但这个方案有明显局限:如果应用配置有其他来源(如环境变量、第三方配置中心),需要手动添加所有配置源;且静态构造函数仅执行一次,配置变更后无法热重载,仅适合配置固定的简单场景。
内容的提问来源于stack exchange,提问作者Philip Stratford
相关产品推荐
相关产品推荐

