asp.net-mvc - 如何使用 Ninject 使用 Identity 2 中的默认身份模型将用户管理器注入(inject)到帐户 Controller

标签 asp.net-mvc asp.net-mvc-5 ninject.web.mvc asp.net-identity-2 asp.net-mvc-controller

我在带有 Identity 2 的 MVC 5 项目上使用 Ninject。

对于其余的数据上下文和 Controller ,我在依赖注入(inject)方面没有任何问题。

对于使用 Identity 2 模型的帐户 Controller ,当我尝试登录时,我得到 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;
        }
    }

注入(inject)所需依赖项的正确方法是什么?我没有创建自定义 UserManager,它是开箱即用的模型,ApplicationUserManager 在 App_Start 下的 IdentityConfig.cs 中定义。

作为旁注:我正在使用 Ninject 的约定扩展:

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. 如您所见,我们有一个方法可以注入(inject)我们想要的所有服务,在本例中我们必须注入(inject) ApplicationUserManagerIUserStore 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();
    
        }
    

    注意:我使用长字符串作为 Identity 上所有键的类型,但是 使用默认值(字符串作为键)应该是相同的。

  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
    
      }
    

关于asp.net-mvc - 如何使用 Ninject 使用 Identity 2 中的默认身份模型将用户管理器注入(inject)到帐户 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25461588/

相关文章:

c# - 如果用户不在给定角色中,则重定向到另一个操作

c# - 在 MVC5 View 中更改按钮样式

asp.net-mvc - ASP.Net MVC 5 + SignalR + Ninject

ninject - 在我的 MVC3 中使用 Ninject 时,我得到一个 Ninject.ActivationException : Error activating IRepository{Ranking} installed via Nuget

asp.net-mvc - ASP.NET MVC RequireHttps

c# - FluentValidation + MVC 扩展(元数据)不能一起工作

asp.net-mvc - 用于 ASP.NET MVC 的组合框

visual-studio-2012 - 添加对 System.Web.WebPages 的引用 3.0 立即更改为 2.0

c# - VS 2013 脚手架中的 "There was an error running the selected code generator"

asp.net-mvc - Ninject - 基于子域动态指定连接字符串