Я начинаю работать с инфраструктурой кэширования для моего сайта ASP.NET MVC. Проблема в том, что я не могу найти разумное место для кэширования данных (кроме "везде" )
Сейчас моя архитектура выглядит так:
Контроллер → Сервисный уровень → Репозиторий. Репозиторий использует Linq для SQL для доступа к данным.
В репозитории раскрываются общие методы, такие как Insert, GetById и GetQueryable, который возвращает IQueryable, который может улучшить уровень обслуживания.
Мне нравится идея кэширования в слое репозитория, так как уровень сервиса не должен заботиться о том, откуда поступают данные. Проблема, однако, связана с недействительностью кэша. Уровень сервиса имеет больше информации о том, когда данные становятся устаревшими, чем репозиторий. Например:
Предположим, что у нас есть таблица Users и таблица Orders (канонический пример). Уровень сервиса предлагает такие методы, как GetOrder (int id), который будет вызывать уровень репозитория:
public Order GetOrder(int id)
{
using(var repo = _repoFactory.Create<Order>())
{
return repo.GetById(id)
}
}
или
repo.GetQueryable(order => order.Id == id && order.HasShipped == false).Single();
Если мы кэшируем на уровне репозитория, похоже, что это будет очень ограниченно, зная, когда данные этого заказа изменились. Предположим, пользователь удален, в результате чего все их заказы будут удалены с помощью CASCADE. Уровень сервиса может привести к аннулированию кеша ордеров, поскольку он знал, что пользователь был просто удален. Однако репозиторий (поскольку это подразделение работы) не будет знать. (Игнорируйте тот факт, что мы не должны запрашивать заказы для удаленного пользователя, так как это просто пример).
В других ситуациях, когда я думаю, это показывает себя. Предположим, мы хотим получить все заказы пользователей:
repo.GetQueryable(order => order.UserId == userId).ToList()
Репозиторий может кэшировать результаты этого запроса, но, если добавлен другой порядок, этот запрос больше недействителен. Тем не менее, только уровень обслуживания знает об этом.
Также возможно, что мое понимание уровня репозитория неверно. Я рассматриваю его как фасад вокруг источника данных (т.е. Переход от L2SQL к EF к чему-либо, уровень сервиса не знает о базовом источнике).