Где кеширование происходит в приложении ASP.NET MVC?

Мне нужно кэшировать некоторые данные, используя System.Web.Caching.Cache. Не уверен, имеет ли это значение, но данные поступают не из базы данных, а из множества пользовательских объектов.

ASP.NET MVC для меня довольно новичок, и мне интересно, где это имеет смысл для этого кэширования?

Модель или контроллер?

На некотором уровне имеет смысл кэшировать на уровне Модель, но я не обязательно знаю последствия этого (если есть). Если кеширование должно выполняться на уровне Контроллер, это повлияет на все запросы или только на текущий HttpContext?

Итак... где должно выполняться кэширование данных приложения и какой хороший способ это сделать?

Update

Спасибо за отличные ответы! Я все еще пытаюсь собрать, где имеет смысл кэшировать данные разные сценарии. Если кешировать всю страницу, то держать ее в представлении имеет смысл, но где рисовать линию, когда она не является всей страницей?

Ответы

Ответ 1

Я думаю, что это в конечном счете зависит от того, что вы кешируете. Если вы хотите кэшировать результат рендеринга страниц, который тесно связан с характером Http запроса и предлагает механизм кэширования уровня ActionFilter.

Если, с другой стороны, вы хотите кэшировать данные, которые управляют самими страницами, то вам следует рассмотреть кэширование уровня модели. В этом случае контроллеру не важно, когда данные были сгенерированы, он просто выполняет логические операции с данными и готовит их для просмотра. Еще один аргумент для кэширования уровня модели - если у вас есть другие зависимости от данных модели, которые не привязаны к вашему контексту Http.

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

Ответ 2

Я не знаю ответа на ваш вопрос, но Джефф Этвуд рассказывает о том, как команда SO выполняла кэширование с использованием среды MVC для stackoverflow.com на недавнем показе hanselminutes, которое могло бы помочь вам:

http://www.hanselminutes.com/default.aspx?showID=152

Ответ 3

Быстрый ответ

Я бы начал с кэширования CONTROLLER, используя атрибут OutputCache, а затем добавьте кэширование модели if обязательный. Это быстрее реализовать и имеет мгновенные результаты.

Подробный ответ (потому что мне нравится звук моего голоса)

Вот пример.

[OutputCache(Duration=60, VaryByParam="None")]
public ActionResult CacheDemo() {
  return View();
}

Это означает, что если пользователь попадает на сайт (для требований к кешу, определенных в атрибуте), меньше работы для выполнения. Если есть только кэширование модели, то, несмотря на то, что логика (и, скорее всего, удаленная БД) кэшируется, веб-сервер все равно должен отображать страницу. Почему это, когда результат рендеринга всегда будет таким же?

Итак, начните с OutputCach ing, а затем перейдите к кэшированию моделей, пока вы тестируете свой сайт.

Выходное кэширование также намного проще начать. Вам не нужно беспокоиться о распространенных проблемах кеширования веб-фермы (если вы являетесь частью фермы) и поставщике кеширования для модели.

Расширенные методы кэширования

Вы также можете использовать кеш-кеш кеша → только часть страницы пользовательского интерфейса: Проверьте это!

Ответ 4

Я бы выбрал кеширование на уровне модели. (В общем, совет, похоже, сводит к минимуму бизнес-логику на уровне контроллера и как можно больше перемещаться в классы моделей.)

Как это сделать:

У меня есть некоторые записи в модели, представленной классом Entry и источник записей (из базы данных или "множества пользовательских объектов" ). В модели я создаю интерфейс для извлечения записей:

public interface IEntryHandler
{
    IEnumerable<Entry> GetEntries();
}

В модели у меня есть фактическая реализация IEntryHandler где записи считываются из кеша и записываются в кеш.

public class EntryHandler : IEntryHandler
{
    public IEnumerable<Entry> GetEntries()
    {
        // Check if the objects are in the cache:
        List<Entry> entries = [Get entries from cache]
        if (entries == null)
        {
            // There were no entries in the cache, so we read them from the source:
            entries = [Get entries from database or 'plethora of custom objects']
            [Save the retrieved entries to cache for later use]
        }
        return entries;
    }
}

Затем контроллер вызовет IEntryHandler:

public class HomeController : Controller
{
    private IEntryHandler _entryHandler;

    // The default constructor, using cache and database/custom objects
    public HomeController()
        : this(new EntryHandler())
    {
    }

    // This constructor allows us to unit test the controller 
    // by writing a test class that implements IEntryHandler
    // but does not affect cache or entries in the database/custom objects
    public HomeController(IEntryHandler entryHandler)
    {
        _entryHandler = entryHandler;
    }

    // This controller action returns a list of entries to the view:
    public ActionResult Index()
    {
        return View(_entryHandler.GetEntries());
    }
}

Таким образом, возможно, unit test контроллер, не касаясь реального кеша/базы данных/пользовательских объектов.

Ответ 5

Я думаю, что кеширование должно каким-то образом быть связано с моделью. Я думаю, что контроллер не должен больше заботиться о данных. Ответственность диспетчера заключается в том, чтобы отображать данные - независимо от того, откуда они взяты - в представлениях.

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

Ответ 6

Все зависит от того, насколько дорога операция. Если у вас есть сложные запросы, возможно, имеет смысл кэшировать данные на уровне контроллера, чтобы запрос не выполнялся снова (до истечения срока действия кэша).

Имейте в виду, что кеширование - очень сложная тема. Существует много разных мест, в которых вы можете хранить кеш:

  • Акамай/CDN-кеширование
  • Браузерное кэширование
  • Кэширование приложений в памяти
  • Объект .NET Cache
  • Директива страницы
  • Распределенный кеш (memcached)