将自定义Repository注入继承IdentityUser的ApplicationUser失败如何解决
问题原因
你遇到的报错根因和你的推测完全一致:ApplicationUser是EF Core管理的实体类型,它的实例默认由EF Core负责构造(比如UserManager查询用户、EF执行查询返回实体时),而非ASP.NET Core DI容器创建。EF Core构造实体时只会识别两类构造函数:
- 无参构造函数
- 所有参数都能和实体的数据库映射属性一一对应的构造函数
你注入的IGenericRepository<Departments>不属于实体属性,自然无法被EF识别绑定,就抛出了对应的构造函数匹配失败异常。这种方式确实无法完成依赖注入。
可行解决方案
方案1:将业务逻辑剥离到独立服务(最推荐,符合单一职责原则)
实体类只负责存储数据属性,领域逻辑放到单独的服务类中,由DI容器正常注入依赖:
// 新增用户领域服务 public class UserDomainService { private readonly IGenericRepository<Departments> _deptRepo; // 依赖正常注入到服务中 public UserDomainService(IGenericRepository<Departments> deptRepo) { _deptRepo = deptRepo; } // 把原ApplicationUser里的方法挪过来,传入用户实例作为参数 public async Task<List<int>> GetManagedDepartmentsAsync(ApplicationUser user) { var depts = await _deptRepo.GetAll(x => x.Manager == user.Employee_id); return depts.Select(x => x.id).ToList(); } }
Startup中注册服务:
services.AddScoped<UserDomainService>();
使用时在Controller/业务类中注入UserDomainService,传入要查询的用户实例调用方法即可,同时也解决了你原代码中用.Result可能导致的死锁问题。
方案2:方法参数注入
如果需要保留方法在ApplicationUser中的定义,可以调整为调用方法时传入依赖:
public class ApplicationUser : IdentityUser { public Int16 Employee_id { get; set; } // 移除构造注入,依赖通过方法参数传入 public async Task<List<int>> DepartmentsManagedAsync(IGenericRepository<Departments> genericRepositoryDepts) { var depts = await genericRepositoryDepts.GetAll(x=>x.Manager==this.Employee_id); return depts.Select(x => x.id).ToList(); } }
调用方法的位置已经可以通过DI拿到IGenericRepository<Departments>实例,直接传入即可。
额外代码问题提示
你当前GenericRepository的GetAll方法中Include逻辑不生效:
// 原代码没有赋值,Include不会生效 query.Include(includeProperty); // 修正为 query = query.Include(includeProperty);
内容的提问来源于stack exchange,提问作者Rich Freeman
相关产品推荐
相关产品推荐

