将服务注入AccountController

时间:2018-10-11 00:05:25

标签: asp.net-mvc dependency-injection

我正在使用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。 ,但是奇怪的是,userManagersignInManager仍然可以访问!

例如,我单击“忘记密码”,无参数构造函数初始化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 :如何通过无参数构造函数注入userManagersignInManager

问题2 :如何将EmailService注入AccountController

2 个答案:

答案 0 :(得分:4)

  

问题1:如何通过无参数构造函数注入userManager和signInManager。

它不是通过无参数构造函数注入的。如果检查控制器,如果尚未在构造函数中设置UserManagerSignInManager,则它们会通过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代码。