Initial IDistributedCache abstraction and implementations.

This includes:
- The IDistributedCache abstraction
- An implementation using MemoryCache
- An implementation using Redis.

This does not include
- Any serialization helpers
- Any concurrency controls (optimistic, locking, etc.).

Notes:
- Resis does not have any notion of sliding expiration, only absolute expiration. It does allow a single entry to contain multiple key-value pairs of data. We use this to store the absolute and sliding expiration values with the data and retrieve them later when we want to re-calculate the expiration.
- Some redis operations are best implemented via LUA script sent to the server. I've done the critical ones that way so far, but there are a few more (like refresh) that could be optimized via script.
That depends on the serializer. If you're working with individual values then you probably only want a byte[]. e.g. primitives like int, bool, etc.. Also, Encoding.Utf8.GetString only takes byte[]. You have to go up to StreamReader to deserialize Streams.  Complex types I agree would probably be using a Stream'd approach (e.g. BinarySerializer).  Regardless we wouldn't want to take a Stream as input because then we'd be forced to read it into a byte[].  From a usage perspective:
byte[] -> primitive is easier than Stream -> byte[] -> primitive
byte[] -> Stream -> complex type is just as easy as Stream -> complex type because of MemoryStream