I'd like to cache objects in ASP.NET MVC. I have a BaseController
that I want all Controllers to inherit from. In the BaseController there is a User
property that will simply grab the User data from the database so that I can use it within the controller, or pass it to the views.
I'd like to cache this information. I'm using this information on every single page so there is no need to go to the database each page request.
I'd like something like:
if(_user is null)
GrabFromDatabase
StuffIntoCache
return CachedObject as User
How do I implement simple caching in ASP.NET MVC?
I took Will's answer and modified it to make the
CacheExtensions
class static and to suggest a slight alteration in order to deal with the possibility ofFunc<T>
beingnull
:I would also consider taking this a step further to implement a testable Session solution that extends the System.Web.HttpSessionStateBase abstract class.
Implementation with a minimal cache locking. The value stored in the cache is wrapped in a container. If the value is not in the cache, then the value container is locked. The cache is locked only during the creation of the container.
@njappboy: Nice implementation. I would only defer the
Generator( )
invocation until the last responsible moment. thus you can cache method invocations too.If you don't need specific invalidation features of ASP.NET caching, static fields are pretty good, lightweight and easy to use. However, as soon as you needed the advanced features, you can switch to ASP.NET's
Cache
object for storage.The approach I use is to create a property and a
private
field. If the field isnull
, the property will fill it and return it. I also provide anInvalidateCache
method that manually sets the field tonull
. The advantage of this approach it that the caching mechanism is encapsulated in the property and you can switch to a different approach if you want.If you want it cached for the length of the request, put this in your controller base class:
If you want to cache for longer, use the replace the ControllerContext call with one to Cache[]. If you do choose to use the Cache object to cache longer, you'll need to use a unique cache key as it will be shared across requests/users.
I like to hide the fact that the data is cached in the repository. You can access the cache through the HttpContext.Current.Cache property and store the User information using "User"+id.ToString() as the key.
This means that all access to the User data from the repository will use cached data if available and requires no code changes in the model, controller, or view.
I have used this method to correct serious performance problems on a system that was querying the database for each User property and reduced page load times from minutes to single digit seconds.