2016-03-21 2 views
0

Я пытаюсь создать пользовательский менеджер, который передается в контроллере, когда он вызывается, и у меня возникают проблемы с пониманием текущей реализации нового проекта MVC5 в C#.Параметры конструктора на действия контроллера

Вот реализация по умолчанию:

public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager) 
{ 
    UserManager = userManager; 
    SignInManager = signInManager; 
} 

прежде всего, что в декларации для них:

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; 
    } 
} 

Теперь из моего понимания SignInManager и UserManager получить создается, когда приложение получает создан для первого время в Startup.Auth.cs, которое выглядит следующим образом:

app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create); 

Итак, всякий раз, когда я вызываю UserManager, я получаю тот первый экземпляр, который был создан при первом запуске проекта.

У меня есть 2 вопроса. Вопрос 1 - это что-то, что я сказал выше, неправильно, и я неправильно понимаю, как работает MVC5?

Вопрос2: Как создаются и передаются контроллеры UserManager и SignInManager в контроллере? Где код, который создает этот первый экземпляр менеджера и передает его в контроллер? Я предполагаю, что это app.CreatePerOwnContext that does it. Если да, могу ли я тогда просто создать своего собственного Менеджера, а затем зарегистрировать его с помощью Owin таким же образом и повторное использование во всем проекте? Будет ли мой код получать последние данные из базы данных, если я это сделаю, а не кешировать?

+1

[Здесь статья] (http://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/), которая показывает шаг за шагом, как удалить локатор службы Если вы вместо этого используете инъекцию зависимостей. Если вы не используете DI, вы не сможете передать диспетчеру контроллеру, вместо этого вам придется обновить его в контроллере. – NightOwl888

ответ

3

Код, который вы показываете, исходит из очень уродливого шаблона MVC5 IMO, который работает из коробки, но делает некоторые уродливые вещи.

Этот конструктор:

public AccountController(ApplicationUserManager userManager, 
     ApplicationSignInManager signInManager) 

заставляет вас думать Owin автомагически впрыскивает менеджеров для вас. Но на самом деле это не так. Вот почему шаблон поставляется с уродливыми свойствами, которые вы задавали в вопросах. Когда вы ничего не меняете в шаблоне, вызывается конструктор по умолчанию (также присутствует в шаблоне). Чтобы попробовать, просто удалите или комментируйте конструктор по умолчанию, и вы увидите, что AccountController больше не может быть создан.

Так что на самом деле происходит то, что оба менеджера расположены с использованием Service Locator anti pattern в геттерах поставляемых свойств.

Так что теперь, когда я вызываю UserManager, я получу тот первый экземпляр, который был создан, когда проект запускался в первый раз?

Нет, это не так. Что эта линия:

app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 

делает, является создание делегата на Create метода обоих менеджеров. Менеджеры кэшируются в рамках запроса Owin. Следующий запрос делегатов вызывается снова, и вы получаете свежий ApplicationUserManager и т. Д.

Чтобы быть немного более многословным эта линия может быть переписано в виде:

Func<ApplicationUserManager> userManagerFactory =() => ApplicationUserMangager.Create(); 
app.CreatePerOwinContext<ApplicationUserManager>(userManagerFactory); 

Так что, если вы бы точки останова здесь:

public ApplicationUserManager UserManager 
{ 
    get 
    { 
     // place breakpoint here 
     return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); 
    } 
// .... 

Вы увидите, что в процессе перехода через код, вы попадете в линию, где вы создали UserManagerFactory, который в свою очередь вызовет метод Create()ApplicationUserManager.

Как UserManager и SignInManager генерируется и передается в контроллер

Это не так! Для этого вам нужно будет использовать инъекцию зависимостей.

Если да, то я тогда просто создать свой собственный менеджер, а затем зарегистрировать его Owin таким же образом и использовать на протяжении всего проекта

Да вы можете. Вы можете полностью реорганизовать ApplicationUserManager, который также получил «бесплатно» в шаблоне. До тех пор, пока вы добавляете заводский метод к методу расширения CreatePerOwinContext.

Будет ли мой код получать последние данные из базы данных, если я это сделаю, а не кешировать? Экземпляры кэшируются по каждой базе запросов. Поэтому каждый запрос вы получите новую, с новым DbContext и т.д.

Я не уверен, как вы знакомы с dependency injection но MVC5 довольно легко рамками, чтобы начать с ним, ИМО.

Я как-то написал blogpost, как настроить мой контейнер DI по выбору (простой инжектор) для использования с шаблоном MVC5. Я также написал несколько ответов здесь о SO относительно этого шаблона: конкретно это one, вас должно заинтересовать. Интересно и это one!

+0

Хорошо, так что первый пример был определенно одним из очень запутанных деталей для меня. Я понимаю, что такое DI. Я признаю, что я еще не совсем понял, зачем это нужно, все еще нужно заниматься исследованиями, но я знаю, что Ninject - очень популярный способ сделать это. Я пытался выяснить, вводит ли OWIN эти два менеджера, и, по внешнему виду, это заблуждало меня, что это так. – Bojan

+0

Вы сказали, что owin будет кэшировать делегатов в запросе OWIN. Какова продолжительность жизни запроса owin? Это каждый раз, когда я перерабатываю свои iis? Это каждый раз, когда страница загружается или она на основе пользователя, сеанс входа в систему? и т. д. – Bojan

+1

Запрос OWIN до тех пор, пока обычный HTTP-запрос до того, как мы получим OWIN. –

Смежные вопросы