如何使用Ninject在Identity 2中将用户管理器注入具有默认身份模型的帐户控制器 [英] How to inject User Manager to Account Controller with default Identity Model in Identity 2 using Ninject
问题描述
我在具有Identity 2的MVC 5项目上使用Ninject.
I use Ninject on a MVC 5 project with Identity 2.
对于其余的数据上下文和使用它的控制器,我对依赖注入没有任何问题.
For rest of data context and controllers using that I have no problems with dependency injection.
对于使用身份2模型的帐户控制器,我尝试登录时得到的是空的UserManager:
For Account controller that uses Identity 2 model I'm getting null UserManager when I try to login:
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中所定义.
What is the proper way to inject required dependencies? I did not create a custom UserManager, it's out of the box model, ApplicationUserManager is as defined in IdentityConfig.cs under App_Start.
作为旁注:我正在使用Ninject的Conventions Extension:
As a side note: I'm using Conventions Extension of Ninject:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind(
x => x.FromThisAssembly()
.SelectAllClasses()
.BindAllInterfaces()
);
谢谢.
推荐答案
在使用Ninject4.0,MVC5.2.3,Identity2.0和Owin3.0.1时,我遇到了同样的问题,在这里您应该正确地处理所有事情./p>
I had the same problem working with Ninject4.0, MVC5.2.3, Identity2.0 and Owin3.0.1, here you should do for working everything properly.
-
首先,您应该从NuGet获得 Ninject.Web.Common.OwinHost ,因为如果您使用Owin,则希望使用NinjectMiddleware.
First of all you should get Ninject.Web.Common.OwinHost from NuGet, because if you working with Owin, you want to use 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 ,我们有:
As you can see, we have a method for injecting all services that we want, in this case we must inject ApplicationUserManager, IUserStore and DbContext. So for RegisterServices in Startup class, we have :
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上所有键的一种,但是 使用defualt(字符串作为键)应该是相同的.
Note: I use long insted of string as a type of all keys on Identity, but using a defualt (string as key) should be the same.
在包含 StartUp 类的一部分的 StartUp.Auth.cs 文件中,我们应将 ConfigureAuth 方法更改为此:>
In StartUp.Auth.cs file that contains partial of StartUp class we should change ConfigureAuth method to this :
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 中使用此属性.(请参阅以后再说)
Note: we get ApplicationUserManager from owin before but now we get it from Ninject kernel.please notice we create a internal static property for DataProtectionProvider and set it from appBuilder, we're going to use this property in IdentityConfig/ApplicationUserManager.(see it later)
现在我们必须更改 ApplicationUserManager ,我们将 Create 方法中的代码从构造函数中删除,并且仅依赖于 IUserStore ,这是最终外观:
Now we must change ApplicationUserManager, we remove code from Create method to constructor with just one dependency with IUserStore, here is the final look:
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 ,如下所示:
at last we can use ApplicationUserManager in our Accountcontroller's constructor like this:
public class AccountController : ApiController
{
private ApplicationUserManager UserManager ;
public AccountController(ApplicationUserManager userManager){
UserManager = userManager;
}
// all apis come here
}
这篇关于如何使用Ninject在Identity 2中将用户管理器注入具有默认身份模型的帐户控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!