如何使用Ninject将用户管理器注入到身份2中的默认身份模型的帐户控制器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用Ninject将用户管理器注入到身份2中的默认身份模型的帐户控制器相关的知识,希望对你有一定的参考价值。
我在带有Identity 2的MVC 5项目中使用Ninject。
对于使用它的其余数据上下文和控制器,我没有依赖注入的问题。
对于使用Identity 2模型的Account控制器,当我尝试登录时,我得到null UserManager:
public class AccountController : Controller
{
private ApplicationUserManager _userManager;
public AccountController()
{
}
public AccountController(ApplicationUserManager userManager)
{
UserManager = userManager;
}
public ApplicationUserManager UserManager {
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
注入所需依赖项的正确方法是什么?我没有创建自定义UserManager,它是开箱即用的模型,ApplicationUserManager是在App_Start下的IdentityConfig.cs中定义的。
作为旁注:我正在使用Ninject的Conventions Extension:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind(
x => x.FromThisAssembly()
.SelectAllClasses()
.BindAllInterfaces()
);
谢谢。
答案
我在使用Ninject4.0,MVC5.2.3,Identity2.0和Owin3.0.1时遇到了同样的问题,在这里你应该做的就是正常工作。
- 首先,你应该从NuGet获得Ninject.Web.Common.OwinHost,因为如果你使用Owin,你想使用NinjectMiddleware。
public partial class StartUp { private IKernel kernel = null; public void Configuration(IAppBuilder app) { kernel = CreateKernel(); app.UseNinjectMiddleware(() => kernel); ConfigureAuth(app); } public IKernel CreateKernel() { var kernel = new StandardKernel(); try { // TODO: Put any other injection which are required. RegisterServices(kernel); return kernel; } catch { kernel.Dispose(); throw; } } }
- 如您所见,我们有一个方法可以注入我们想要的所有服务,在这种情况下,我们必须注入ApplicationUserManager,IUserStore和DbContext。因此对于Startup类中的RegisterServices,我们有:
private static void RegisterServices(IKernel kernel) { kernel.Bind<DbContext>().To<ApplicationDbContext>(); kernel.Bind<IUserStore<User, long>>().To<UserStore<User, Role, long, UserLogin, UserRole, UserClaim>>(); kernel.Bind<ApplicationUserManager>().ToSelf(); }
注意:我使用long insted of string作为Identity上所有键的类型,但使用defualt(字符串作为键)应该是相同的。 - 在包含部分StartUp类的StartUp.Auth.cs文件中,我们应该将ConfigureAuth方法更改为:
internal static IDataProtectionProvider DataProtectionProvider { get; private set; } public void ConfigureAuth(IAppBuilder app) { DataProtectionProvider = app.GetDataProtectionProvider(); //app.CreatePerOwinContext<ApplicationUserManager(ApplicationUserManager.Create) app.CreatePerOwinContext<ApplicationUserManager>( (option, context) => { var kernl = context.Get<IKernel>(); return kernel.Get<ApplicationUserManager>(); }); //rest of the code }
注意:我们之前从owin获取ApplicationUserManager,但现在我们从Ninject内核获取它。请注意我们为DataProtectionProvider创建一个内部静态属性并从appBuilder设置它,我们将在IdentityConfig / ApplicationUserManager中使用此属性。(稍后再看) ) - 现在我们必须更改ApplicationUserManager,我们将代码从Create方法移除到只有一个IUserStore依赖的构造函数,这里是最后的样子:
public class ApplicationUserManager : UserManager<User,long> { public ApplicationUserManager(IUserStore<User,long> store) :base(store) { this.UserValidator = new UserValidator<User, long>(this) { AllowOnlyAlphanumericUserNames = false, RequireUniqueEmail = true }; // Configure validation logic for passwords this.PasswordValidator = new PasswordValidator { RequiredLength = 6, RequireNonLetterOrDigit = true, RequireDigit = true, RequireLowercase = true, RequireUppercase = true, }; var dataProtectionProvider = Startup.DataProtectionProvider; // this is unchanged if (dataProtectionProvider != null) { IDataProtector dataProtector = dataProtectionProvider.Create("ASP.NET Identity"); this.UserTokenProvider = new DataProtectorTokenProvider<User,long>(dataProtector); } } }
- 最后我们可以在Accountcontroller的构造函数中使用ApplicationUserManager,如下所示:
public class AccountController : ApiController { private ApplicationUserManager UserManager ; public AccountController(ApplicationUserManager userManager){ UserManager = userManager; } // all apis come here }
另一答案
您可以尝试从代码中删除问题中提到的行,并将其替换为以下内容:
public AccountController()
: this(new UserManager<ApplicationUser>(new Microsoft.AspNet.Identity.EntityFramework.UserStore<ApplicationUser>(new ApplicationDbContext())))
{
}
public AccountController(UserManager<ApplicationUser> userManager)
{
UserManager = userManager;
}
public UserManager<ApplicationUser> UserManager { get; private set; }
以上是关于如何使用Ninject将用户管理器注入到身份2中的默认身份模型的帐户控制器的主要内容,如果未能解决你的问题,请参考以下文章