如何使用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时遇到了同样的问题,在这里你应该做的就是正常工作。

  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; } } }
  2. 如您所见,我们有一个方法可以注入我们想要的所有服务,在这种情况下,我们必须注入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(字符串作为键)应该是相同的。
  3. 在包含部分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中使用此属性。(稍后再看) )
  4. 现在我们必须更改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); } } }
  5. 最后我们可以在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中的默认身份模型的帐户控制器的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Ninject 与 HttpClient 一起使用

将用户凭据从HttpRequestContext注入服务层

使用 Ninject OWIN 中间件在 OWIN 启动中注入 UserStore

如何将基本身份验证质询转发到报告管理器 url

使用 Ninject

如何在c#类库中使用Ninject