Где кеширование происходит в приложении 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)