ASP.NET Identity中使用Autofac注册UserManager遇报错求助
解决Autofac注册UserManager时的"ApplicationUser不在当前上下文模型中"及后续DbContext未注册错误
看起来你在Autofac配置Identity相关依赖时踩了两个常见坑:一是UserManager/UserStore和Repository的DbContext实例不共享,二是DbContext的注册类型不完整导致依赖解析失败。我来一步步帮你解决:
问题根源分析
- 第一个错误:你注册的
UserStore和UsersRepository使用的是不同的ApplicationDbContext实例,导致UserManager操作的上下文和Repository的上下文不是同一个,EF就会认为ApplicationUser不在当前模型里。 - 第二个错误:你之前尝试的方案里,
UserStore需要具体的ApplicationDbContext类型,但你只注册了它的接口IApplicationDbContext,Autofac找不到对应类型的服务,所以报错。
正确的Autofac配置方案
先替换你的AutofacConfig.Configure()代码,我会逐行解释:
public static void Configure() { var builder = new ContainerBuilder(); // 1. 同时注册DbContext的自身类型和接口 // 为什么要AsSelf?因为UserStore的构造函数需要具体的ApplicationDbContext实例 builder.RegisterType<ApplicationDbContext>() .AsSelf() .As<IApplicationDbContext>() .InstancePerRequest(); // 2. 注册UserStore,Autofac会自动注入上面注册的ApplicationDbContext builder.RegisterType<UserStore<ApplicationUser>>() .As<IUserStore<ApplicationUser>>() .InstancePerRequest(); // 3. 注册UserManager,用lambda明确指定构造参数 // 避免Autofac选错UserManager的重载构造函数 builder.Register(c => new UserManager<ApplicationUser>(c.Resolve<IUserStore<ApplicationUser>>())) .InstancePerRequest(); // 4. 注册你的仓储 builder.RegisterType<UsersRepository>() .As<IUsersRepository<ApplicationUser>>() .InstancePerRequest(); // 别忘了注册WebAPI控制器 builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); var container = builder.Build(); GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container); }
优化你的UsersRepository
另外注意一个细节:UserManager.Create()方法内部已经会调用DbContext的SaveChanges(),你不需要再手动调用,否则可能导致重复提交或上下文状态冲突。简化后的仓储代码:
public class UsersRepository : IUsersRepository<ApplicationUser> { public IApplicationDbContext DbInstance { get; } private readonly UserManager<ApplicationUser> _userManager; // 不需要注入IUserStore,UserManager内部已经持有它 public UsersRepository(IApplicationDbContext dbInstance, UserManager<ApplicationUser> userManager) { DbInstance = dbInstance; _userManager = userManager; } public void Create(ApplicationUser user) { var createResult = _userManager.Create(user); if (!createResult.Succeeded) { // 抛出包含错误信息的异常,方便上层处理 throw new InvalidOperationException($"创建用户失败:{string.Join(", ", createResult.Errors)}"); } } // 其他实现方法... }
为什么这样能解决问题
- 共享DbContext实例:所有依赖(UserStore、UsersRepository)在同一个请求周期内使用的是同一个
ApplicationDbContext实例,EF上下文状态一致,不会出现"实体不在模型中"的错误。 - 完整的DbContext注册:通过
AsSelf()注册了ApplicationDbContext自身类型,满足了UserStore对具体DbContext类型的依赖需求。 - 明确的UserManager构造:用lambda指定构造参数,避免Autofac在UserManager的多个重载构造函数中选错,确保注入正确的
IUserStore实例。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

