DBContext更改后如何在控制器内创建新的UserManager对象
Posted
技术标签:
【中文标题】DBContext更改后如何在控制器内创建新的UserManager对象【英文标题】:How to create new UserManager object inside controller after DBContext changed 【发布时间】:2021-04-04 23:29:12 【问题描述】:在我的DbContext
更改为Controller 内的新connectionString 后,我希望有一个刷新的UserManager 对象,我在Controller 中注入了UserManager
,但很明显它将始终具有来自DI 的最后一个DbContext
引用,而不是新创建的dbcontext
。
我已经尝试如下。
this.DbContext = new ApplicationDbContext(Configuration, optionsBuilder.Options);
this._userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(DbContext), null, new PasswordHasher<ApplicationUser>(), null, null, null, null, null, null);
它运行良好,但缺少大部分 UserManager
功能,例如
_userManager.CheckPasswordAsync(user, loginModel.Password)
因为我将大部分参数作为空值传递。
我应该怎么做才能以最简单的方式让 UserManger
和新的 DbContext
完全正常工作?
【问题讨论】:
只是好奇你为什么要做这样的事情? 【参考方案1】:使用依赖注入,这就是所有提到的工具的使用方式。
private DbContext DbContext get;
private UserManager<IdentityUser> UserManager get;
public MyController(DbContext dbContext, UserManager<IdentityUser> userManager)
DbContext = dbContext;
UserManager = userManager;
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-5.0
这是一个关于如何为 EF Core 设置依赖注入的页面:
https://docs.microsoft.com/en-us/ef/core/dbcontext-configuration/#dbcontext-in-dependency-injection-for-aspnet-core
假设您已经拥有services.AddDefaultIdentity(...)
和services.AddDbContext(...)
,注入UserManager
和YourProjectDbContext
本来就应该在您的控制器中工作。
【讨论】:
【参考方案2】:您可以尝试创建服务并在服务中使用 UserManger,然后使用 Startup.ConfigureServices 方法中的 Transient 操作配置服务。瞬态操作总是不同的,每次检索服务都会创建一个新实例。然后,您可以在控制器中使用此服务。请检查以下步骤:
创建一个 UserManagerRepository 服务(在此服务中您可以创建方法并使用 UserManager 方法):
public interface IUserManagerRepository
void Write(string message);
public class UserManagerRepository : IUserManagerRepository, IDisposable
private bool _disposed;
private readonly UserManager<IdentityUser> _userManager;
public UserManagerRepository(UserManager<IdentityUser> userManager)
_userManager = userManager;
public void Write(string message)
// _userManager.ChangePasswordAsync()
Console.WriteLine($"UserManagerRepository: message");
public void Dispose()
if (_disposed)
return;
Console.WriteLine("UserManagerRepository.Dispose");
_disposed = true;
在 Startup.ConfigureServices 方法中使用以下代码配置服务:
services.AddTransient<IUserManagerRepository, UserManagerRepository>();
之后,在控制器动作方法中手动调用服务。
public IActionResult Index()
var services = this.HttpContext.RequestServices;
var log = (IUserManagerRepository)services.GetService(typeof(IUserManagerRepository));
log.Write("Index method executing");
var log2 = (IUserManagerRepository)services.GetService(typeof(IUserManagerRepository));
log2.Write("Index method executing");
var log3 = (IUserManagerRepository)services.GetService(typeof(IUserManagerRepository));
log3.Write("Index method executing");
return View();
截图如下:
参考:
Tutorial: Use dependency injection in .NET
Dependency injection guidelines
Dependency injection in ASP.NET Core
【讨论】:
所以在再次调用该服务后,userManager 将使用新创建的 AppDbContext 进行初始化? _userManager 仍然持有对旧 dbContext 的引用,新 dbContext 具有不同的连接字符串 @SabirHossain 当然,因为代码注入了身份模型提供的UserManager<IdentityUser>
,这仍然取决于配置的DbContext
(在您的应用程序启动中)。这个答案绝对不是你想要的。
我知道,@Hopeless 我该怎么做才能用新创建的 DbContext 刷新 UserManger,你可以看到我是如何做到的,但我需要一个功能齐全的 UserManager以上是关于DBContext更改后如何在控制器内创建新的UserManager对象的主要内容,如果未能解决你的问题,请参考以下文章
使用DBContext ChangeTracker编写基于事件的SignalR Notification Service - 关注点分离