Is there any guide for caching patterns in ASP.NET 5

In ASP.NET 5, we have two interfaces for caching IDistributedCache and IMemoryCache, and then we also have LocalCache, which is an implementation of IDistributedCache that uses MemoryCache internally.

IMemoryCache seems to have an api that I'm used to, you put an object of any type and you return an object that you can revert back to the original type. When using MemoryCache, I think that no serialization is involved, the object is simply stored directly in memory, so api is simpler.

IDistibutedCache is similar to what we should use to develop scalable cloud applications, but it has a less attractive api, because we pass an array of bytes and return an array of bytes. In this case, the objects must be serializable, and we must serialize them ourselves in order to put them in the cache and deserialize them after extraction, for example, in this code fragment:

public async Task<TreeNode<NavigationNode>> GetTree() { if (rootNode == null) { await cache.ConnectAsync(); byte[] bytes = await cache.GetAsync(cacheKey); if (bytes != null) { string json = Encoding.UTF8.GetString(bytes); rootNode = BuildTreeFromJson(json); } else { rootNode = await BuildTree(); string json = rootNode.ToJsonCompact(); await cache.SetAsync( cacheKey, Encoding.UTF8.GetBytes(json), new DistributedCacheEntryOptions().SetSlidingExpiration( TimeSpan.FromSeconds(100)) ); } } return rootNode; } 

In this particular example, I use custom serialization and deserialization because the object in this example needs some help with serialization, because it is not just a class.

For a more general use of the cache with easily serializable objects, it seems that I have to implement some kind of helper cache or wrapper around IDistributedCache to make an api that looks more like IMemoryCache, so I can just pass the object and get the object back by key and reduce the complexity and duplication of caching code. Internally, I suppose my CacheHelper class will use standard json serialization, or is there something else I should use?

Are there any plans for this type of CacheHelper in the structure itself, or should I implement my own?

I think that especially in environments such as Azure, I should probably implement caching for most of the things often obtained from the SqlAzure database in order to reduce costs, and IDistributeCache makes it easy to connect various caching solutions to Azure cache or Redit, etc. . DI

Is this the right approach or are there any recommendations for a better approach or template?

When using LocalCache, is there a performance difference using MemoryCache directly?

Should we always or almost always use IDistributedCache or are there specific scripting scenarios where using IMemoryCache would be preferable?

+6
source share
1 answer

I posted this issue in a Caching GitHub project for ASP.NET.

There is already a set of IDistributedCache extension methods here that we can add (all of this is open source, so we can fix it ourselves and send a pull request :)).

Note that BinaryFormatter is not available in .NET Core (not sure if it will ever be), so I wrapped it with #if DNX451 and included the BinaryWriter and BinaryReader extension methods that can be used at both times. Also note that if you use the BinaryFormatter extension methods, you will need to add the [Serializable] attribute to your objects that you want to serialize.

 public static class CacheExtensions { // Omitted existing extension methods... public static async Task<bool> GetBooleanAsync(this IDistributedCache cache, string key) { byte[] bytes = await cache.GetAsync(key); using (MemoryStream memoryStream = new MemoryStream(bytes)) { BinaryReader binaryReader = new BinaryReader(memoryStream); return binaryReader.ReadBoolean(); } } public static async Task<char> GetCharAsync(this IDistributedCache cache, string key) { byte[] bytes = await cache.GetAsync(key); using (MemoryStream memoryStream = new MemoryStream(bytes)) { BinaryReader binaryReader = new BinaryReader(memoryStream); return binaryReader.ReadChar(); } } public static async Task<decimal> GetDecimalAsync(this IDistributedCache cache, string key) { byte[] bytes = await cache.GetAsync(key); using (MemoryStream memoryStream = new MemoryStream(bytes)) { BinaryReader binaryReader = new BinaryReader(memoryStream); return binaryReader.ReadDecimal(); } } public static async Task<double> GetDoubleAsync(this IDistributedCache cache, string key) { byte[] bytes = await cache.GetAsync(key); using (MemoryStream memoryStream = new MemoryStream(bytes)) { BinaryReader binaryReader = new BinaryReader(memoryStream); return binaryReader.ReadDouble(); } } public static async Task<short> GetShortAsync(this IDistributedCache cache, string key) { byte[] bytes = await cache.GetAsync(key); using (MemoryStream memoryStream = new MemoryStream(bytes)) { BinaryReader binaryReader = new BinaryReader(memoryStream); return binaryReader.ReadInt16(); } } public static async Task<int> GetIntAsync(this IDistributedCache cache, string key) { byte[] bytes = await cache.GetAsync(key); using (MemoryStream memoryStream = new MemoryStream(bytes)) { BinaryReader binaryReader = new BinaryReader(memoryStream); return binaryReader.ReadInt32(); } } public static async Task<long> GetLongAsync(this IDistributedCache cache, string key) { byte[] bytes = await cache.GetAsync(key); using (MemoryStream memoryStream = new MemoryStream(bytes)) { BinaryReader binaryReader = new BinaryReader(memoryStream); return binaryReader.ReadInt64(); } } public static async Task<float> GetFloatAsync(this IDistributedCache cache, string key) { byte[] bytes = await cache.GetAsync(key); using (MemoryStream memoryStream = new MemoryStream(bytes)) { BinaryReader binaryReader = new BinaryReader(memoryStream); return binaryReader.ReadSingle(); } } public static async Task<string> GetStringAsync(this IDistributedCache cache, string key) { byte[] bytes = await cache.GetAsync(key); using (MemoryStream memoryStream = new MemoryStream(bytes)) { BinaryReader binaryReader = new BinaryReader(memoryStream); return binaryReader.ReadString(); } } public static Task SetAsync(this IDistributedCache cache, string key, bool value, DistributedCacheEntryOptions options) { byte[] bytes; using (MemoryStream memoryStream = new MemoryStream()) { BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(value); bytes = memoryStream.ToArray(); } return cache.SetAsync(key, bytes, options); } public static Task SetAsync(this IDistributedCache cache, string key, char value, DistributedCacheEntryOptions options) { byte[] bytes; using (MemoryStream memoryStream = new MemoryStream()) { BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(value); bytes = memoryStream.ToArray(); } return cache.SetAsync(key, bytes, options); } public static Task SetAsync(this IDistributedCache cache, string key, decimal value, DistributedCacheEntryOptions options) { byte[] bytes; using (MemoryStream memoryStream = new MemoryStream()) { BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(value); bytes = memoryStream.ToArray(); } return cache.SetAsync(key, bytes, options); } public static Task SetAsync(this IDistributedCache cache, string key, double value, DistributedCacheEntryOptions options) { byte[] bytes; using (MemoryStream memoryStream = new MemoryStream()) { BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(value); bytes = memoryStream.ToArray(); } return cache.SetAsync(key, bytes, options); } public static Task SetAsync(this IDistributedCache cache, string key, short value, DistributedCacheEntryOptions options) { byte[] bytes; using (MemoryStream memoryStream = new MemoryStream()) { BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(value); bytes = memoryStream.ToArray(); } return cache.SetAsync(key, bytes, options); } public static Task SetAsync(this IDistributedCache cache, string key, int value, DistributedCacheEntryOptions options) { byte[] bytes; using (MemoryStream memoryStream = new MemoryStream()) { BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(value); bytes = memoryStream.ToArray(); } return cache.SetAsync(key, bytes, options); } public static Task SetAsync(this IDistributedCache cache, string key, long value, DistributedCacheEntryOptions options) { byte[] bytes; using (MemoryStream memoryStream = new MemoryStream()) { BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(value); bytes = memoryStream.ToArray(); } return cache.SetAsync(key, bytes, options); } public static Task SetAsync(this IDistributedCache cache, string key, float value, DistributedCacheEntryOptions options) { byte[] bytes; using (MemoryStream memoryStream = new MemoryStream()) { BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(value); bytes = memoryStream.ToArray(); } return cache.SetAsync(key, bytes, options); } public static Task SetAsync(this IDistributedCache cache, string key, string value, DistributedCacheEntryOptions options) { byte[] bytes; using (MemoryStream memoryStream = new MemoryStream()) { BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(value); bytes = memoryStream.ToArray(); } return cache.SetAsync(key, bytes, options); } #if DNX451 public static async Task<T> GetAsync<T>(this IDistributedCache cache, string key) { byte[] bytes = await cache.GetAsync(key); using (MemoryStream memoryStream = new MemoryStream(bytes)) { BinaryFormatter binaryFormatter = new BinaryFormatter(); return (T)binaryFormatter.Deserialize(memoryStream); } } public static Task SetAsync<T>(this IDistributedCache cache, string key, T value) { return SetAsync(cache, key, value, new DistributedCacheEntryOptions()); } public static Task SetAsync<T>(this IDistributedCache cache, string key, T value, DistributedCacheEntryOptions options) { byte[] bytes; using (MemoryStream memoryStream = new MemoryStream()) { BinaryFormatter binaryFormatter = new BinaryFormatter(); binaryFormatter.Serialize(memoryStream, value); bytes = memoryStream.ToArray(); } return cache.SetAsync(key, bytes, options); } #endif } 
+2
source

All Articles