我正在使用ASP.NET MVC 5,并且正在使用MS在创建新项目时提供的默认模板。
我想向EmailService
中添加注入的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;
}
我正在使用ninject,这就是我解决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();
}
现在,我的emailService
没有注入AccountController
中。因此,我开始调试代码,并注意到无参数的构造函数用于初始化AccountController
。 ,但是奇怪的是,userManager
和signInManager
仍然可以访问!
例如,我单击“忘记密码”,无参数构造函数初始化AccountController
,然后调用以下操作方法(它是MVC项目模板的一部分):
[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);
}
问题1 :如何通过无参数构造函数注入userManager
和signInManager
。
问题2 :如何将EmailService
注入AccountController
?
答案 0 :(得分:4)
问题1:如何通过无参数构造函数注入userManager和signInManager。
它不是通过无参数构造函数注入的。如果检查控制器,如果尚未在构造函数中设置UserManager
和SignInManager
,则它们会通过OWIN上下文延迟加载。
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;
}
}
这通常是默认模板的一部分。
问题2:如何将我的EmailService注入AccountController?
删除无参数构造函数和延迟加载。然后,确保所有依赖项都在依赖关系解析器中注册,以便可以通过框架使用的IDependencyResolver
解析对象图。
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;
答案 1 :(得分:1)
这是我最后所做的:
public AccountController(IEmailService emailService)
{
_emailService = emailService;
}
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager, IEmailService emailService)
: this(emailService)
{
UserManager = userManager;
SignInManager = signInManager;
}
我没有更改任何ninject代码。