Jordan Earls committed ee39b4d


  • Participants
  • Parent commits a274b1d

Comments (0)

Files changed (3)

File CacheGen.sln

 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CacheGen.Tests", "CacheGen.Tests\CacheGen.Tests.csproj", "{6D0638D3-F01E-423B-A2CE-DB910D4CE944}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4DB649A2-5CFC-46BB-BCF3-CD4E2902E86D}"
+	ProjectSection(SolutionItems) = preProject
+ =
+	EndProjectSection
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
 		{6D0638D3-F01E-423B-A2CE-DB910D4CE944}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{6D0638D3-F01E-423B-A2CE-DB910D4CE944}.Release|Any CPU.Build.0 = Release|Any CPU
+	GlobalSection(NestedProjects) = preSolution
+	EndGlobalSection
 	GlobalSection(MonoDevelopProperties) = preSolution
 		StartupItem = CacheGen\CacheGen.csproj

File CacheGen/UntrackedCacheDictionary.cs

 namespace Earlz.CacheGen
+	/// <summary>
+	/// This is a cache pass through dictionary which does no tracking of what is possibly cached.
+	/// It relies on the `.ToString` function of the key type being unique. 
+	/// This means that two identical objects with different references will be detected as the same cache key, which may or may not be desirable.
+	/// </summary>
 	public class UntrackedCacheDictionary<K,V> : ICacheDictionary<K,V>
 		StoreToCache StoreTo;
+== Introduction ==
+This is a T4 template and library to make caching awesome and pain free! This is accomplished
+by utilizing the code-generation abilities of T4 to write the really hard and tedious code for you. 
+This leaves you with a static class, which passes through to a chosen `CacheMechanism`, with the correct type. 
+Finally! No more manual casting, remembering what the caching options should be, nor what the magic string is. 
+== Example == 
+Let's say you want to cache blog posts and the generated HTML for some high traffic page in our ASP.Net website
+First, you'd do something like this in the T4 template:
+	var gen=new CacheGenerator("MyCache", "new ASPCacheMechanism()"); //use ASP.Net's caching mechanism(built in)
+	gen.Namespace="Earlz.CacheGen.Examples"; //set the namespace to whatever you like
+	gen.AddItem(new CacheObject{Name="HighTrafficPage", Type="string"}); //add our high traffic page cache
+	gen.AddItem(new CacheObject{Name="BlogPosts", KeyType="int", ValueType="BlogPost"}); //add our BlogPosts cache with a key type of int and value type of BlogPost
+	Write(gen.ToString()); //write it out to generated C# file
+From there, it's magically very easy to use the cache
+	BlogPost mypost=MyCache.BlogPosts[some_id]; //no casting! 
+	string somepage=MyCache.HighTrafficPage; 
+	//a super easy pattern to load the cache if it doesn't exist
+	var post= MyCache.BlogPosts[id] ?? MyCache.BlogPosts[id]=LoadPost(id);
+== ICacheDictionary == 
+There are currently two options for the CacheDictionary. Which one wokrs best for you will depend on your use case:
+* TrackingCacheDictionary
+* UntrackedCacheDictionary
+The untracked version is the default and I'll discuss it first. Basically, it relies on a `.ToString` implementation for the key type which is unique, but not random. 
+If you use this version, you must make sure that for two identical key objects (or identical enough for your needs) the `.ToString()` method will return the same
+string. And that if two key objects are clearly not identical, they must return a different result from `.ToString()`. Despite these requirements, this untracked dictionary is the
+fastest and most performant of the two. It passes almost directly through to the CacheMechanism. There are never any locks.
+The tracked version on the other hand is nice when you need to use a key type which you can't modify. For instance, if a library provides a "Widget" and you want to use that as a key,
+but it's `ToString()` does not meet the above requirements(note, it DOES require that it's `.Equals` method works appropriately though), then the tracked dictionary is for you.
+There are many downsides to the tracking though. For one, it's much more complex. Complexity in concurrent code spells trouble. I've tested it and had it reviewed by a second pair of eyes, but
+there could always be that one stray race condition that I didn't catch. Also, the tracking requires a few locks and it can possibly break if you have a LOT of different keys which will
+seldom be acessed. Tracking a very large number of keys might make you hit the maximum object size limit, as well as possibly leaking memory. I recommend only using it if you really have to. 
+== CacheMechanism == 
+This is an extremely simple to implement interface to your caching method. Basically, nulls can not be cacheable is the only strict requirement. If a value is passed in as null, then
+the value associated with the passed in key should be removed from the cache. Also, these methods MUST be thread-safe.