无参构造函数解析服务致仓储层出现InvalidOperationException异常
解决RoleProvider中DbContext已释放的问题
首先咱们来拆解下你遇到的问题根源:
ASP.NET的RoleProvider是单例生命周期的——框架只会初始化它一次,之后一直复用这个实例。而你在构造函数里通过DependencyResolver.Current.GetService<IUserService>()获取的IUserService,如果你的DI配置里它是请求级生命周期(这是最常见的配置,DbContext通常也绑定请求生命周期),那么第一次请求结束后,对应的DbContext就会被DI容器释放。之后再调用GetRolesForUser时,你缓存的_userService引用的DbContext已经处于 disposed 状态,自然就抛出了那个异常。
解决方案1:每次调用方法时获取服务实例
不要在构造函数里缓存_userService,而是在每次调用GetRolesForUser方法时才去获取IUserService。这样每次都会拿到当前请求上下文里有效的服务实例,DbContext也处于可用状态:
public SiteRole() { // 这里不再缓存_userService } public override string[] GetRolesForUser(string nickname) { var userService = DependencyResolver.Current.GetService<IUserService>(); return new string[] { userService.GetRoleForUser(nickname) }; }
解决方案2:优化UserService中的查询逻辑
另外你的GetRoleForUser方法还有两个潜在问题,也可能间接导致异常:
FirstOrDefault可能返回null,直接访问.Role.Name会触发NullReferenceException- 如果没有提前
Include关联的Role实体,EF可能会用延迟加载去查询Role,若此时DbContext已释放,同样会报错
所以修改UserService的代码:
public string GetRoleForUser(string nickname) { // 提前Include关联的Role,避免延迟加载 var user = DbContext.Users.Include(u => u.Role) .FirstOrDefault(u => u.Nickname == nickname); // 处理用户不存在的情况,返回默认角色或者根据业务逻辑调整 return user?.Role?.Name ?? "Guest"; }
额外建议
尽量避免在单例服务中持有请求级服务的引用,这是DI里常见的生命周期不匹配问题。上面的方案1通过每次获取新实例避开了这个问题,也是最适配你当前场景的做法。
内容的提问来源于stack exchange,提问作者Tim Maes
相关产品推荐
相关产品推荐

