我在带有 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 时遇到了同样的问题,这里你应该做的是让一切正常工作。
首先,您应该从 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; } } }
如您所见,我们有一个方法可以注入(inject)我们想要的所有服务,在本例中我们必须注入(inject) 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(); }
注意:我使用长字符串作为 Identity 上所有键的类型,但是 使用默认值(字符串作为键)应该是相同的。
在包含部分 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 }
关于asp.net-mvc - 如何使用 Ninject 使用 Identity 2 中的默认身份模型将用户管理器注入(inject)到帐户 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25461588/