title: How to implement a caching model without violating MVC pattern?
body: <p>I have an ASP.NET MVC 3 (Razor) Web Application, with a particular page which is <strong>highly database intensive</strong>, and user experience is of the upmost priority.</p>
  
  <p>Thus, i am introducing caching on this particular page.</p>
  
  <p>I'm trying to figure out a way to implement this caching pattern whilst keeping my controller <strong>thin</strong>, like it currently is without caching:</p>
  
  <pre><code>public PartialViewResult GetLocationStuff(SearchPreferences searchPreferences)
  {
     var results = _locationService.FindStuffByCriteria(searchPreferences);
     return PartialView("SearchResults", results);
  }
  </code></pre>
  
  <p>As you can see, the controller is very thin, as it should be. It doesn't care about how/where it is getting it's info from - that is the job of the service.</p>
  
  <p>A couple of notes on the flow of control:</p>
  
  <ol>
  <li>Controllers get DI'ed a particular <strong>Service</strong>, depending on it's area. In this example, this controller get's a <strong>LocationService</strong></li>
  <li><strong>Services</strong> call through to an <code>IQueryable&lt;T&gt;</code> <strong>Repository</strong> and materialize results into <code>T</code> or <code>ICollection&lt;T&gt;</code>.</li>
  </ol>
  
  <p>How i want to implement caching:</p>
  
  <ul>
  <li><strong>I can't use Output Caching</strong> - for a few reasons. First of all, this action method is invoked from the client-side (jQuery/AJAX), via <code>[HttpPost]</code>, which according to HTTP standards should not be cached as a request. Secondly, i don't want to cache purely based on the HTTP request arguments - the cache logic is a lot more complicated than that - there is actually two-level caching going on.</li>
  <li>As i hint to above, i need to use regular data-caching, e.g <code>Cache["somekey"] = someObj;</code>.</li>
  <li>I don't want to implement a generic caching mechanism where <em>all</em> calls via the service go through the cache first - <strong>i only want caching on this particular action method</strong>.</li>
  </ul>
  
  <p>First thought's would tell me to create another service (which inherits <strong>LocationService</strong>), and provide the caching workflow there (check cache first, if not there call db, add to cache, return result).</p>
  
  <p>That has two problems:</p>
  
  <ol>
  <li>The services are basic <strong>Class Libraries</strong> - no references to anything extra. I would need to add a reference to <code>System.Web</code> here.</li>
  <li>I would have to access the HTTP Context outside of the web application, which is considered bad practice, not only for testability, but in general - right?</li>
  </ol>
  
  <p>I also thought about using the <code>Models</code> folder in the Web Application (which i currently use only for <strong>ViewModels</strong>), but having a cache service in a models folder just doesn't sound right.</p>
  
  <p>So - any ideas? Is there a MVC-specific thing (like Action Filter's, for example) i can use here? </p>
  
  <p>General advice/tips would be greatly appreciated.</p>