【问题标题】:How to create new UserManager object inside controller after DBContext changedDBContext更改后如何在控制器内创建新的UserManager对象
【发布时间】: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 完全正常工作?

【问题讨论】:

  • 只是好奇你为什么要做这样的事情?

标签: c# asp.net-core usermanager


【解决方案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(...),注入UserManagerYourProjectDbContext 本来就应该在您的控制器中工作。

【讨论】:

    【解决方案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&lt;IdentityUser&gt;,这仍然取决于配置的DbContext(在您的应用程序启动中)。这个答案绝对不是你想要的。
    • 我知道,@Hopeless 我该怎么做才能用新创建的 DbContext 刷新 UserManger,你可以看到我是如何做到的,但我需要一个功能齐全的 UserManager
    猜你喜欢
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 2015-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多