Шаблон репозитория ASP.NET / Кэширование на уровне служб

Я начинаю работать над инфраструктурой кэширования для моего сайта ASP.NET MVC . Проблема в том, что я не могу найти разумного места для кэширования данных (кроме ' везде ')

Сейчас моя архитектура выглядит так:

Контроллер -> Уровень обслуживания -> Репозиторий. Репозиторий использует Linq to SQL для доступа к данным.

Репозиторий предоставляет общие методы, такие как Insert, GetById и GetQueryable, которые возвращают IQueryable, который уровень сервиса может дополнительно уточнить.

Мне нравится идея разместить кэширование на уровне репозитория, поскольку уровень сервиса не должен заботиться о том, откуда берутся данные. Проблема заключается в том, что кеш-память недействительна. Уровень сервиса содержит больше информации о том, когда данные становятся устаревшими, чем репозиторий. Например:

Предположим, у нас есть таблица «Пользователи» и таблица «Заказы» (канонический пример). Уровень сервиса предлагает такие методы, как 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();

Если мы кэшируем на уровне репозитория, похоже, что было бы очень мало знать, когда эти данные заказа изменились. Предположим, что пользователь был удален, в результате чего все его заказы были удалены с помощью КАСКАДА. Уровень сервиса мог сделать кеш заказов недействительным, поскольку он знал, что пользователь был только что удален. Однако репозиторий (поскольку это единица работы) не будет знать. (Игнорируйте тот факт, что мы не должны запрашивать заказы для удаленного пользователя, поскольку это всего лишь пример).

Есть и другие ситуации, в которых, я думаю, это проявляется. Предположим, мы хотим получить все заказы пользователей:

repo.GetQueryable(order => order.UserId == userId).ToList()

Репозиторий может кэшировать результаты этого запроса, но, если добавлен другой заказ, этот запрос больше не действителен. Однако об этом знает только уровень сервиса.

Также возможно, что я неверно понимаю уровень репозитория. Я как бы рассматриваю это как фасад вокруг источника данных (т.е. при переходе с L2SQL на EF на что-то еще, уровень сервиса не знает о базовом источнике).

11
задан mfanto 25 April 2011 в 17:38
поделиться