Сеанс ASP.NET MVC против глобального против кэша - PullRequest
7 голосов
/ 27 мая 2009

У меня есть приложение, написанное в vanilla ASP.NET, которое я хотел бы перенести на ASP.NET MVC.

Меня, однако, смущает правильное место для сохранения предметов. Мне нужно упорствовать по нескольким причинам:

  1. Я бы хотел, чтобы у всех было одиночное соединение с базой данных, обернутое в объект в стиле "хранилище" или "менеджер".
  2. У каждого пользователя есть объект пользователя, который необходимо сохранять для каждого сеанса.

Как правило, я бы сказал, что # 1 будет сохранен как статический элемент в Globals.asax, который можно нажать, используя Global.Repository или аналогичный.

И я бы обычно сказал, что # 2 должно быть свойством с резервным хранилищем сеанса где-то в базовом классе страниц.

Теперь я сбит с толку тем, что слышал, что сеансы изменились в MVC, и Global.asax больше не содержит тот же класс. Кроме того, концепция страниц была удалена, поэтому добавление свойства в базовый класс контроллера кажется ... неправильным.

Что сказать, yall?

Ответы [ 4 ]

10 голосов
/ 27 мая 2009

Ваша база данных перейдет в базовый класс для ваших контроллеров. Этот базовый класс должен расширять Controller, а все ваши контроллеры должны расширять базовый класс. Вот небольшой пример:

public class BaseController : Controller
{
    private AuthServices _auth;
    private LogHelper _log;
    private Repository _repository;

    /// <summary>
    /// <see cref="AuthServices"/>
    /// </summary>
    protected AuthServices Authorization
    {
        get { return _auth ?? (_auth = new AuthServices()); }
    }

    /// <summary>
    /// <see cref="LogHelper"/>
    /// </summary>
    protected LogHelper Log
    {
        get { return _log ?? (_log = new LogHelper()); }
    }

    /// <summary>
    /// <see cref="Repository"/>
    /// </summary>
    protected Repository Repository
    {
        get { return _repository ?? (_repository = new Repository()); }
    }
}

Обратите внимание на ленивый экземпляр. Это позволяет мне проникнуть перед запуском тестов и установить мои личные поля с помощью макетов.

Что касается сеанса, ваш пользовательский объект все еще может быть сохранен в сеансе, как в традиционном приложении ASP.NET. Почти все вокруг (Response, Cache, Session и т. Д.), Но некоторые из них были обернуты классами из System.Web.Abstractions, чтобы их можно было смоделировать для тестирования. Все они по-прежнему ведут себя одинаково, хотя некоторые из них не следует использовать в их традиционной роли (например, не Response.Redirect, возвращайте ActionResult, например RedirectToRouteResult, который выполняет перенаправление).

Что касается обоснования ваших вопросов ....

Не делайте акцент на одном подключении к БД. В зависимости от вашей реализации это может быть даже плохой идеей, поскольку запросы могут наступать друг на друга. Просто откройте свое соединение, используйте его и утилизируйте / закройте, когда закончите.

Кроме того, одним из самых больших изменений, которые приносит MVC, является отказ от модели с состоянием, которую традиционная ASP.NET пыталась привнести в веб-разработку. Все эти рамки и представления больше не существуют (не обращайте внимания на человека за занавесом). Чем меньше у вас состояния, тем менее сложным и надежным будет ваше веб-приложение. Попробуйте, вам это может понравиться.

4 голосов
/ 27 мая 2009

Если вы используете сеансы, я бы порекомендовал иметь класс сеансов, так что вам нужно указывать имя строки только один раз в коде, и это также даст вам IntelliSence.

 public static class SessionHandler
{   
    // User Values
    private static string _userID = "UserID";
    private static string _userRole = "UserRole";

    public static string UserID
    {
        get
        {
            if (HttpContext.Current.Session[SessionHandler._userID] == null)
            { return string.Empty; }
            else
            { return HttpContext.Current.Session[SessionHandler._userID].ToString(); }
        }
        set
        { HttpContext.Current.Session[SessionHandler._userID] = value; }

    }

    public static string UserRole
    {
        get
        {
            if (HttpContext.Current.Session[SessionHandler._userRole] == null)
            { return string.Empty; }
            else
            { return HttpContext.Current.Session[SessionHandler._userRole].ToString(); }
        }
        set
        { HttpContext.Current.Session[SessionHandler._userRole] = value; }

    }
}
2 голосов
/ 27 мая 2009

Сессии вообще не изменились в MVC. Класс GlobalApplication в Global.asax также все еще существует. Страницы также существуют, и вы захотите ссылаться на репозиторий в контроллере, а не на страницу. Добавление свойства в базовый класс контроллера - это нормально; Я делаю это все время.

1 голос
/ 15 июня 2010

Вы можете создать связыватель модели для инкапсуляции состояния.

(см. Книгу Стива Сандерсона о внедрении его корзины)

С помощью связывателя модели у вас есть доступ к controllerContext, который имеет HttpContext.

...