DBContext更改后如何在控制器内创建新的UserManager对象

问题描述

我想在我的 DbContext 更改为控制器内的新 connectionString 后刷新 UserManager 对象,我已经在控制器中注入了 UserManager 但很明显它总是有最后一个 {{ 1}} 引用来自 DI,而不是新创建的 DbContext

我尝试过如下。

dbcontext

它运行良好,但缺少大部分 this.DbContext = new ApplicationDbContext(Configuration,optionsBuilder.Options); this._userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(DbContext),null,new PasswordHasher<ApplicationUser>(),null); 功能,例如 UserManager 因为我将大部分参数作为 null 传递。 我应该怎么做才能以最简单的方式使用新的 _userManager.CheckPasswordAsync(user,loginModel.Password) 获得完全正常工作的 Usermanger

解决方法

您可以尝试创建一个服务并使用该服务中的 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();
    }

截图如下:

enter image description here

参考:

Tutorial: Use dependency injection in .NET

Dependency injection guidelines

Dependency injection in ASP.NET Core

,

使用依赖注入,这就是所有提到的工具的使用方式。

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(...),那么注入 UserManagerYourProjectDbContext 本质上应该只在您的控制器中工作。