将控制器方法重构为DI容器服务后无法被识别该如何解决?
问题原因
- 服务类存在自引用循环依赖:你的
GetAZCredidentials类中定义了private readonly GetAZCredidentials _context;字段,构造函数未对该字段赋值,且后续用_context访问ApplicationUsers数据集,相当于让服务自己依赖自己,DI容器无法完成实例解析。
- 服务类存在自引用循环依赖:你的
- 缺失必要依赖注入:你需要访问数据库上下文,但代码中没有注入正确的
DbContext实例,所有对_context.ApplicationUsers的调用都会触发报错。
- 缺失必要依赖注入:你需要访问数据库上下文,但代码中没有注入正确的
- 调用逻辑错误:你调用
GetRequiredService获取的是服务类实例,直接和整数1做判断属于逻辑错误,需要调用实例下的GetAZCredidentials1()方法获取返回值再做判断。
- 调用逻辑错误:你调用
- (若存在)服务注册错误:如果未在
Program.cs(.NET 6+)或Startup.cs的ConfigureServices方法中正确注册services.AddTransient<GetAZCredidentials>();,也会导致DI无法识别服务。
- (若存在)服务注册错误:如果未在
- 调用时机错误:从调用栈看你是在
Configure管道构建阶段调用服务解析,此时如果服务是Scoped生命周期,或者容器未完成构建,也会抛出解析异常。
- 调用时机错误:从调用栈看你是在
修复步骤
- 修正服务类的依赖定义,注入正确的DbContext和IHttpContextAccessor:
namespace QlikviewServer.Services { public class GetAZCredidentials { // 替换为你项目实际的DbContext类名 private readonly YourDbContext _dbContext; private readonly IHttpContextAccessor _httpContextAccessor; public HttpContext HttpContext { get => _httpContextAccessor.HttpContext; set => _httpContextAccessor.HttpContext = value; } public GetAZCredidentials(YourDbContext dbContext, IHttpContextAccessor httpContextAccessor) { _dbContext = dbContext; _httpContextAccessor = httpContextAccessor; } public int GetAZCredidentials1() { PrincipalContext ctx = new PrincipalContext(ContextType.Domain); UserPrincipal user1 = UserPrincipal.Current; string displayName2 = user1.DisplayName; string displayName = user1.SamAccountName; string DistinguishedName = user1.DistinguishedName; string[] values = DistinguishedName.Split(','); string domain = values[6]; string[] values2 = domain.Split('='); string domain2 = values2[1].Trim(); string UserPrincipalName2 = user1.UserPrincipalName; var comp = values[4]; var company_id = comp.Split('='); var company_id2 = company_id[1].Trim(); List<ApplicationUser> groupsad = (from m in _dbContext.ApplicationUsers select new ApplicationUser { ApplicationUserId = m.ApplicationUserId, UserName = m.UserName, NameAdmin = m.NameAdmin, DisplayName = m.DisplayName, UserPrincipalName = m.UserPrincipalName }).ToList(); var groups2 = (from m in _dbContext.ApplicationUsers select m).ToList(); for (int i = 0; i < groupsad.Count; i++) { if (string.IsNullOrEmpty(groupsad[i].NameAdmin.Trim())) { groupsad[i].NameAdmin = groupsad[i].NameAdmin.Trim(); } if (string.IsNullOrEmpty(groupsad[i].UserName.Trim())) { groupsad[i].UserName = groupsad[i].UserName.Trim(); } _dbContext.ApplicationUsers.Where(it => it.NameAdmin == groupsad[i].NameAdmin).ToList() .ForEach( it => { var it2 = it.NameAdmin.TrimEnd(); if (it2 == displayName) { it.DisplayName = displayName2; } } ); if (string.IsNullOrEmpty(groupsad[i].UserPrincipalName.Trim())) { _dbContext.ApplicationUsers.Where(it => it.NameAdmin == groupsad[i].NameAdmin).ToList() .ForEach( it => { var it2 = it.NameAdmin.TrimEnd(); if (it2 == displayName) { it.UserPrincipalName = UserPrincipalName2; } } ); } else { groupsad[i].UserPrincipalName = groupsad[i].UserPrincipalName.Trim(); } } foreach (ApplicationUser f in groupsad) { if (f.NameAdmin.Trim() == displayName) { if (f.UserName.Trim() == "reader" || (f.UserName.Trim() == "admin" && domain2 == "Vionet")) { return 1; } } return 2; } return 3; } } }
- 注册相关服务:
如果是.NET 6+版本,在Program.cs的服务注册阶段添加以下代码:
// 注册IHttpContextAccessor builder.Services.AddHttpContextAccessor(); // 注册自定义服务 builder.Services.AddTransient<GetAZCredidentials>();
如果是.NET 5及以下版本,在Startup.cs的ConfigureServices方法里添加:
services.AddHttpContextAccessor(); services.AddTransient<GetAZCredidentials>();
- 修正调用逻辑:
// 获取服务实例 var azService = serviceProvider.GetRequiredService<GetAZCredidentials>(); // 调用方法获取返回值 var result1 = azService.GetAZCredidentials1(); if (result1 != 1) { // 你的业务逻辑 }
- 如果是在Configure管道阶段调用,需要手动创建Scope:
app.Use(async (context, next) => { using var scope = context.RequestServices.CreateScope(); var azService = scope.ServiceProvider.GetRequiredService<GetAZCredidentials>(); var result1 = azService.GetAZCredidentials1(); // 逻辑处理 await next(); });
内容的提问来源于stack exchange,提问作者Aris Biris
相关产品推荐
相关产品推荐

