asp.net-mvc - Injecting a service into AccountController
问题描述
I am using ASP.NET MVC 5, and I am using the default template that MS provides when creating a new project.
I want to add an injected EmailService
into AccountController
:
[Authorize]
public class AccountController : ControllerBase
{
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
private IEmailService _emailService; // <-- added this field to MS template
public AccountController()
{
}
// I have added emailService to constructor parameter
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager, IEmailService emailService)
{
UserManager = userManager;
SignInManager = signInManager;
_emailService = emailService;
}
I am using ninject, and this is how I resolve IEmailService
:
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IEmailService>().To<MyEmailService>().InRequestScope();
}
Now, my emailService
is not getting injected into AccountController
... so I started debugging the code and noticed that the parameter-less constructor is used to initialize the AccountController
... but the strange thing is, userManager
and signInManager
are still accessible!
For example, I click on Forgot password, the parameter-less constructor initializes AccountController
, and then the following action method is called (which is part of MVC project template):
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
if (ModelState.IsValid)
{
/* UserManager is successfully injected!! */
var user = await UserManager.FindByNameAsync(model.Email);
// some code here to build an email...
/* _emailService is NULL!! */
await _emailService.SendEmailAsync(email);
}
Question 1: How is it possible userManager
and signInManager
are injected through the parameter-less constructor.
Question 2: How can I inject my EmailService
into AccountController
?
解决方案
Question 1: How is it possible userManager and signInManager are injected through the parameter-less constructor.
It is not being injected via parameterless constructor. If you check the controller you will see the UserManager
and SignInManager
lazy loading via OWIN context if they were not already set in the constructor.
public ApplicationSignInManager SignInManager {
get {
return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
}
private set {
_signInManager = value;
}
}
public ApplicationUserManager UserManager {
get {
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set {
_userManager = value;
}
}
That was usually part of the default template.
Question 2: How can I inject my EmailService into AccountController?
Remove the parameter-less constructor and the lazy loading. Then make sure all dependencies are registered in the dependency resolver so that the object graph can be resolved via the IDependencyResolver
used by the framework.
var kernel = new StandardKernel();
RegisterServices(kernel);
GlobalConfiguration.Configuration.DependencyResolver =
new Ninject.Web.WebApi.NinjectDependencyResolver(kernel); //Web API
System.Web.Mvc.DependencyResolver
.SetResolver(new Ninject.Web.Mvc.NinjectDependencyResolver(kernel)); // MVC
return kernel;
推荐阅读
- flutter - 每次 Provider 加载数据时显示 CircularProgressIndicator
- angular6 - 无法正确访问 EmbeddedView 中的上下文对象
- javascript - 从文本元素中获取小数
- c# - C# 中的 Powerpoint 加载项应用程序,需要访问演示文稿所有者详细信息
- javascript - 如何在一个函数中从 2 个 api 获取数据并在对话框流卡实现中显示
- amazon-web-services - DynamoDB Global Table
- python-3.x - 如何在 sqlalchemy 中组合同一类的数据库存储实例和应用程序硬编码实例?
- javascript - ajax自动刷新div在x秒后隐藏div
- .net - 带有 .NET Core 3.0 的 VSTO
- ios - What is the alternative to WebIntent on iOS in Ionic 4?