Внедрение службы в AccountController - PullRequest
0 голосов
/ 11 октября 2018

Я использую 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?

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Это то, что я сделал в итоге:

public AccountController(IEmailService emailService)
{
    _emailService = emailService;
}

public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager, IEmailService emailService)
    : this(emailService)
{
    UserManager = userManager;
    SignInManager = signInManager;
}

Я не изменил ни одного кода кода.

0 голосов
/ 11 октября 2018

Вопрос 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;
...