Community Page
- john-sheehan.com/blog Jump to website »
-
Subscribe -
Community
-
Top Commenters
-
Popular Threads
-
Recent Comments
- Hey John, congratulations -- and, you're welcome!
- How would you set this up to use multiple domains on the server in different iis sites?
- Alternatively, a small change made Wordpress'e original htaccess file if you can use: RewriteCond %{HTTP_HOST} !^(tuncay\.kinali\.net) [NC] RewriteCond %{HTTP_HOST} !^$ RewriteRule ^/(.*)$...
- I also think a killer app for Twitter isn't out there yet, is TweetDeck the best positioned to complete this vision?
- Perhaps a upcoming Google Wave application will do what you want..
Just Sayin' More Words
A blog by John Sheehan
I wanted a single, common method for caching items for either the length of a request (in HttpContext.Current.Items) or longer (in HttpContext.Current.Cache). Hereâs what I came up with.
Thereâs three common operations I use for caching: storing an item, removing an i ... Continue reading »
Thereâs three common operations I use for caching: storing an item, removing an i ... Continue reading »
8 months ago
One thing though, and that is that in your implementations of the Get-method you access the storage twice. One time to check if there is anything in storage, and another time to actually get it. Since you don't lock anything, another thread can remove the item you are looking for. This will happen when you use the storage frequently.
Something like the following will solve this.
public T Get<T>(string key)
{
T item = (T)HttpContext.Current.Cache[key];
if (item == null)
item = default(T);
return item;
}
8 months ago
8 months ago
return HttpRuntime.Cache[key] as T;
This will automatically return default(T) if the cached item doesn't exist. Using Maarten's code if you try to get an object from the cache that can not correctly cast to the type T you will get can't convert exception for the object.
8 months ago
8 months ago
var item = HttpRuntime.Cache[key];
return item is T ? (T) item : default(T);
Which is basically what the as operator does anyway.
9 months ago
I can offer some insight into the model that John was following when he created the cache manager. Following a pattern similar to this allows you to create loosely coupled code.
With your question if you implemented the caching solution using only the specific classes if you ever decided you wanted to change your caching backing store from HttpRuntime.Cache (note: John, you should reference the cache as HttpRuntime.Cache instead of Httpcontext.Current.Cache, calling the context just causes extra processing to just resolve to HttpRuntime.Cache) to a sql data store or to a memory caching solution like memcache or velocity you will now have to go into you code and change every single usage of RequestProvider to use MemCacheProvider or whatever other implementation you wish to use.
With a loosely coupled implementation that John created here, if you ever wish to switch from one provider to another you only ever need to change where it instantiates CacheManger to use the new provider instead. This brings me to my point about Enterprise Library's CacheManager having a factory method for creating the caching providers usage, this will allow you to only need to declare the CacheProviders once in your code and no matter how many times you change the concrete implmentation of ICacheProvider you will only ever need to change 1 line of code in the entirety of your project which is a great thing indeed.
This idea of creating shared services that you can plug and play based off of interfaces is the basis of the idea of "Inversion of Control" or IoC that creates very robust and completely decoupled projects. Some of the most well known IoC frameworks are Microsoft's Unity, Spring.NET, Castle Windsor, Ninject, StructureMap to name a few there are quite a bit of frameworks out there for IoC. Creating loosely coupled code is definitely getting to the point where it is mandatory for a project to be a well made solution.
9 months ago
8 months ago
ICacheProvider cache = new ShortTermProvider();
or
CacheManager cache = new CacheManager(new ShortTermProvider());
8 months ago
8 months ago
9 months ago
9 months ago
9 months ago
http://msdn.microsoft.com/en-us/library/cc30910...
The big difference in implementation of the Caching block is that the providers are created through a singleton factory which in my opinion makes alot of sense since cache stores generally are only ever 1 and only 1 per type of store so relying on a factory to handle the management of instances of the providers makes sense to me more than doing new __Provider(....) anytime you wish to access the cache.
9 months ago
public static Cache Cache {
get {
if (System.Web.HttpContext.Current != null && System.Web.HttpContext.Current.Cache != null)
return System.Web.HttpContext.Current.Cache;
return System.Web.HttpRuntime.Cache;
}
}
That allows me to utilize the same concepts in Windows Forms and Windows Service applications....just some FYI
9 months ago
9 months ago
You should take a look at some Dependency Injection framework (castle, spring.net, Nunit) and apply it instead of creating new CacheManager directly in code.
9 months ago
I'm a fan of the whole loosely coupled thing, however there are some times that I require (well, want more then require) a few different caching strategies for one project. Very data dependent of course. Any thoughts?
9 months ago
The example above is perfect for if you need different caching strategies in a project. Just create a provider for each strategy and use that provider when needed.
9 months ago
9 months ago
9 months ago
lock the cache when you're writing to it, for occasions where data is being refreshed by another process.
lock (HttpContext.Current.Cache)
{
}
9 months ago
discussing locks and caching (at least in regards to ASP.NET) before. I
think it would be interesting to hear what the risk is of not using a lock.
9 months ago
public delegate T GetObjectDelegate<T>();
public V GetItemValue<V>(string objectID, V nullValue, GetObjectDelegate<V> getobject)
{
if (Cache[objectID] == null)
{
if (getobject == null)
return default(V);
V obj = getobject();
if (obj != null)
{
Insert(objectID, obj);
return obj;
}
else
return nullValue;
}
return (V)Cache[objectID];
}
in this way you'll be able to verify if an object is in cache and load the object in cache if it's not just in a single line
CacheManager.GetItemValue("key", null, delegate(){return getobjfromdb();})
7 months ago