I posted this issue on the ASP.NET Caching GitHub project.
There is already a set of IDistributedCache extension methods here that we can potentially add to (It's all open source so we can fix this ourselves and submit a pull request :)).
Note that BinaryFormatter is not available in .NET Core (Not sure if it ever will be) so I wrapped it with #if DNX451 and included the BinaryWriter and BinaryReader extension methods which both runtimes can use. Note also that if you are using the BinaryFormatter extension methods, you will need to add the [Serializable] attribute to your entities 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
}
IMemoryCachehas been specially designed to accept non-serializable objects thatIDistributedCacheimplementations couldn't handle (e.g aCompilationResultor aCompilerCacheEntry). If you want to easily switch between in-memory and distributed caching, useIDistributedCache: the default implementation (LocalCache) usesIMemoryCache.BinaryWriterorBitConverterfor instance (stricto sensu, it's not really a serializer).BinaryWriterandBinaryReaderin aspnet/Security to serialize an authentication ticket: github.com/aspnet/Security/blob/dev/src/…. Of course, this kind of "manual serialization" has its own downsides: you need a specific serialization format for every type you want to support, yourWrite/Readcalls must respect the same order and every change made to the serialization format is a "breaking change" (that's why we use aVersionhint)... but it's blazingly fast.JsonConvertequivalent that simply takes anobjectand tries to serialize it,BinaryWriteris clearly not the way to go.