Where should caching occur in an ASP.NET MVC application?

前端 未结 6 2030
有刺的猬
有刺的猬 2021-02-07 12:14

I\'m needing to cache some data using System.Web.Caching.Cache. Not sure if it matters, but the data does not come from a database, but a plethora of custom obj

6条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-02-07 12:43

    I would choose caching at the model level. (In general, the advice seems to be to minimize business logic at the controller level and move as much as possible into model classes.)

    How about doing it like this:

    I have some entries in the model represented by the class Entry and a source of entries (from a database, or 'a plethora of custom objects'). In the model I make an interface for retrieving entries:

    public interface IEntryHandler
    {
        IEnumerable GetEntries();
    }
    

    In the model I have an actual implementation of IEntryHandler where the entries are read from cache and written to cache.

    public class EntryHandler : IEntryHandler
    {
        public IEnumerable GetEntries()
        {
            // Check if the objects are in the cache:
            List 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;
        }
    }
    

    The controller would then call the 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());
        }
    }
    

    This way it is possible to unit test the controller without touching real cache/database/custom objects.

提交回复
热议问题