Я бы выбрал кеширование на уровне модели.
(Как правило, совет состоит в том, чтобы минимизировать бизнес-логику на уровне контроллера
и двигайтесь как можно больше в классы моделей.)
Как насчет этого:
У меня есть несколько записей в модели, представленной классом 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());
}
}
Таким образом, можно выполнить модульное тестирование контроллера, не касаясь реального кэша / базы данных / пользовательских объектов.