如何将 DI 与 UserManager 和 UserStore 结合使用
How to use DI with UserManager and UserStore
给定 MVC 控制器构造函数的典型设置,将 UserManager
(需要 UserStore
)传递给它的父 class,如何将其转换为通过 IoC 注入?
从这里开始:
public AccountController()
: this(new UserManager<ApplicationUser>(
new UserStore<ApplicationUser>(new ApplicationDbContext())))
{
}
我会这样想:
public AccountController(IUserStore store)
: this(new UserManager<ApplicationUser>(store)))
{
}
虽然这样做,当然会失去IdentityDbContext
。
应如何设置 IoC 以及应如何定义构造函数以允许注入 UserManager、UserStore 和 IdentityDbContext?
您需要创建一些 类 以便于注入。
让我们从 UserStore 开始。创建所需的接口并让它继承自 IUserStore<ApplicationUser>
public IUserStore : IUserStore<ApplicationUser> { }
创建如下实现。
public ApplicationUserStore : UserStore<ApplicationUser>, IUserSTore {
public ApplicationUserStore(ApplicationDbContext dbContext)
:base(dbContext) { }
}
然后可以在 OP 中根据需要完成 UserManager。
public class ApplicationUserManager : UserManager<ApplicationUser> {
public ApplicationUserManager(IUserSTore userStore) : base(userStore) { }
}
所以现在剩下的就是确保您决定使用哪个 IoC 容器注册必要的 类。
ApplicationDbContext --> ApplicationDbContext
IUserStore --> ApplicationUserStore
如果您想更进一步并抽象化 UserManager,则只需创建一个接口来公开您想要的功能
public interface IUserManager<TUser, TKey> : IDisposable
where TUser : class, Microsoft.AspNet.Identity.IUser<TKey>
where TKey : System.IEquatable<TKey> {
//...include all the properties and methods to be exposed
IQueryable<TUser> Users { get; }
Task<TUser> FindByEmailAsync(string email);
Task<TUser> FindByIdAsync(TKey userId);
//...other code removed for brevity
}
public IUserManager<TUser> : IUserManager<TUser, string>
where TUser : class, Microsoft.AspNet.Identity.IUser<string> { }
public IApplicationUserManager : IUserManager<ApplicationUser> { }
你的经理是否继承了它。
public class ApplicationUserManager : UserManager<ApplicationUser>, IApplicationUserManager {
public ApplicationUserManager(IUserSTore userStore) : base(userStore) { }
}
现在这意味着控制器现在可以依赖于抽象而不是实现问题
private readonly IApplicationUserManager userManager;
public AccountController(IApplicationUserManager userManager) {
this.userManager = userManager;
}
然后再次在 IoC 容器中注册接口和实现。
IApplicationUserManager --> ApplicationUserManager
更新:
如果您喜欢冒险并想抽象身份框架本身,请查看
给定 MVC 控制器构造函数的典型设置,将 UserManager
(需要 UserStore
)传递给它的父 class,如何将其转换为通过 IoC 注入?
从这里开始:
public AccountController()
: this(new UserManager<ApplicationUser>(
new UserStore<ApplicationUser>(new ApplicationDbContext())))
{
}
我会这样想:
public AccountController(IUserStore store)
: this(new UserManager<ApplicationUser>(store)))
{
}
虽然这样做,当然会失去IdentityDbContext
。
应如何设置 IoC 以及应如何定义构造函数以允许注入 UserManager、UserStore 和 IdentityDbContext?
您需要创建一些 类 以便于注入。
让我们从 UserStore 开始。创建所需的接口并让它继承自 IUserStore<ApplicationUser>
public IUserStore : IUserStore<ApplicationUser> { }
创建如下实现。
public ApplicationUserStore : UserStore<ApplicationUser>, IUserSTore {
public ApplicationUserStore(ApplicationDbContext dbContext)
:base(dbContext) { }
}
然后可以在 OP 中根据需要完成 UserManager。
public class ApplicationUserManager : UserManager<ApplicationUser> {
public ApplicationUserManager(IUserSTore userStore) : base(userStore) { }
}
所以现在剩下的就是确保您决定使用哪个 IoC 容器注册必要的 类。
ApplicationDbContext --> ApplicationDbContext
IUserStore --> ApplicationUserStore
如果您想更进一步并抽象化 UserManager,则只需创建一个接口来公开您想要的功能
public interface IUserManager<TUser, TKey> : IDisposable
where TUser : class, Microsoft.AspNet.Identity.IUser<TKey>
where TKey : System.IEquatable<TKey> {
//...include all the properties and methods to be exposed
IQueryable<TUser> Users { get; }
Task<TUser> FindByEmailAsync(string email);
Task<TUser> FindByIdAsync(TKey userId);
//...other code removed for brevity
}
public IUserManager<TUser> : IUserManager<TUser, string>
where TUser : class, Microsoft.AspNet.Identity.IUser<string> { }
public IApplicationUserManager : IUserManager<ApplicationUser> { }
你的经理是否继承了它。
public class ApplicationUserManager : UserManager<ApplicationUser>, IApplicationUserManager {
public ApplicationUserManager(IUserSTore userStore) : base(userStore) { }
}
现在这意味着控制器现在可以依赖于抽象而不是实现问题
private readonly IApplicationUserManager userManager;
public AccountController(IApplicationUserManager userManager) {
this.userManager = userManager;
}
然后再次在 IoC 容器中注册接口和实现。
IApplicationUserManager --> ApplicationUserManager
更新:
如果您喜欢冒险并想抽象身份框架本身,请查看