【发布时间】:2017-04-04 11:29:45
【问题描述】:
当用户登录(从 Google 外部登录)时,我需要通过执行对数据库的读取并添加返回的值来添加自定义声明。我正在使用 Ninject 进行依赖注入,以将具有接口的控制器注入到我的业务层服务中。
所以我找到了 identityModels.cs 方法来添加声明:
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
string userId = userIdentity.GetUserId();
//var _iUserBLL = (IUserBLL)System.Web.Mvc.DependencyResolver.Current.GetService(typeof(IUserBLL));
//UserBO objUser = _iUserBLL.GetById(userId);
//userIdentity.AddClaim(new Claim("Value1", objUser.Value1));
//userIdentity.AddClaim(new Claim("Value2", objUser.Value2));
return userIdentity;
}
这里 System.Web.Mvc.DependencyResolver.Current.GetService 行失败并导致它崩溃。这适用于其他地方,我也尝试过与注入控制器相同的方法,例如:
public class MyController : Controller
{
private readonly IUserBLL _iUserBLL;
public MyController (IUserBLL iUserBLL)
{
_iUserBLL = iUserBLL;
}
}
甚至:
[Inject]
public IUserBLL _iUserBLL { get; set; }
但在 GenerateUserIdentityAsync 方法中使用时,_iUserBLL 为空。有什么想法可以在这里注入我的 IUserBLL 来进行自定义数据库调用吗?
更多信息 - 如果您不熟悉此方法,它是在具有个人用户帐户的 Visual Studio 项目中生成的身份代码的一部分。
全班是这样的:
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity>
GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
...
}
}
所以我在这里尝试了构造函数,它不起作用:
public class ApplicationUser : IdentityUser
{
private readonly IUserBLL _iUserBLL;
public ApplicationUser (IUserBLL iUserBLL)
{
_iUserBLL = iUserBLL;
}
...
}
IdentityUser 在预先提供的 identity.entityframework 类的内部工作中声明,并从我无法编辑的内部调用,所以我很困惑如何处理这个?
感谢您的回复 Sam,它让我找到了解决方案。这是我最终得到的代码。我在使用静态“Create”方法时遇到了问题,所以我改用了 [Inject] 属性。有没有办法改变静态“创建”方法以在构造函数中使用 IUserBLL?这是我正在工作的代码:
在 App_Start/IdentityConfig.cs 中
// Configure the application sign-in manager which is used in this application.
public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
[Inject]
public IUserBLL _iUserBLL { get; set; }
public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager)
: base(userManager, authenticationManager)
{
}
public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
{
var userIdentity = user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
UserBO objUser = _iUserBLL.GetById(user.Id);
userIdentity.Result.AddClaim(new Claim("Claim1", objUser.Value1));
userIdentity.Result.AddClaim(new Claim("Claim2", objUser.Value2));
return userIdentity;
}
public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
{
return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
}
}
在我的 NinjectWebCommon.cs 中,我还包括这些行,是我所有绑定的额外内容:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<System.Security.Principal.IPrincipal>().ToMethod(context => HttpContext.Current.User).InRequestScope();
kernel.Bind<ApplicationUserManager>().ToMethod(context => HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>()).InRequestScope();
kernel.Bind<ApplicationSignInManager>().ToMethod((context) =>
{
var cbase = new HttpContextWrapper(HttpContext.Current);
return cbase.GetOwinContext().Get<ApplicationSignInManager>();
});
...
}
【问题讨论】:
-
如果方法是从可以成功注入相关接口的地方调用的,则将其作为方法参数传递
-
为什么不在包含 GenerateUserIdentityAsync 方法的类中为 IUserBLL 进行构造函数注入,就像在构造函数中一样?
-
干杯,我在上面添加了更多信息。理想情况下,我只想拥有
public class ApplicationUser : IdentityUser { [Inject] public IUserBLL _iUserBLL { get; set; }但 _iUserBLL 始终为空。我是否在 NinjectWebCommon.cs 中遗漏了一些东西来告诉 Ninject 注入这个?
标签: asp.net-mvc asp.net-identity-2 ninject.web.mvc