From 88bc96e4e53e9271bdd0971a9e31d283fb10e730 Mon Sep 17 00:00:00 2001 From: Administrator Date: Tue, 22 Sep 2020 22:29:38 +0800 Subject: [PATCH] Added ISerializer Non Generic Deserialize overload method . Added IRedisDatabase Non Generic GetAsync overload method . --- .../Abstractions/IRedisDatabase.cs | 9 ++++ .../ISerializer.cs | 12 ++++- .../Implementations/RedisDatabase.cs | 11 +++++ .../BinarySerializer.cs | 11 ++++- .../JilSerializer.cs | 7 +++ .../MsgPackObjectSerializer.cs | 15 ++++++ .../NewtonsoftSerializer.cs | 10 +++- .../ProtobufSerializer.cs | 11 ++++- .../SystemTextJsonSerializer.cs | 9 +++- .../Utf8JsonSerializer.cs | 9 +++- .../CacheClientTestBase.cs | 49 +++++++++++++++++++ 11 files changed, 147 insertions(+), 6 deletions(-) diff --git a/src/core/StackExchange.Redis.Extensions.Core/Abstractions/IRedisDatabase.cs b/src/core/StackExchange.Redis.Extensions.Core/Abstractions/IRedisDatabase.cs index 3f653e4b..1c3f40eb 100644 --- a/src/core/StackExchange.Redis.Extensions.Core/Abstractions/IRedisDatabase.cs +++ b/src/core/StackExchange.Redis.Extensions.Core/Abstractions/IRedisDatabase.cs @@ -74,6 +74,15 @@ public partial interface IRedisDatabase /// Task GetAsync(string key, TimeSpan expiresIn, CommandFlags flag = CommandFlags.None); + /// + /// Get the object with the specified key from Redis database + /// + /// The cache key. + /// The type of the object to convert to and return. + /// Behaviour markers associated with a given command + /// Null if not present, otherwise the instance of T. + Task GetAsync(string key, Type returnType, CommandFlags flag = CommandFlags.None); + /// /// Adds the specified instance to the Redis database. /// diff --git a/src/core/StackExchange.Redis.Extensions.Core/ISerializer.cs b/src/core/StackExchange.Redis.Extensions.Core/ISerializer.cs index cdb081e5..b1777652 100644 --- a/src/core/StackExchange.Redis.Extensions.Core/ISerializer.cs +++ b/src/core/StackExchange.Redis.Extensions.Core/ISerializer.cs @@ -1,4 +1,4 @@ -using System.Threading.Tasks; +using System; namespace StackExchange.Redis.Extensions.Core { @@ -23,5 +23,15 @@ public interface ISerializer /// The instance of the specified Item /// T Deserialize(byte[] serializedObject); + + /// + /// Deserializes the specified bytes. + /// + /// The serialized object. + /// The type of the object to convert to and return. + /// + /// The instance of the specified Item + /// + object Deserialize(byte[] serializedObject, Type returnType); } } diff --git a/src/core/StackExchange.Redis.Extensions.Core/Implementations/RedisDatabase.cs b/src/core/StackExchange.Redis.Extensions.Core/Implementations/RedisDatabase.cs index 265299ca..81aa9d0c 100644 --- a/src/core/StackExchange.Redis.Extensions.Core/Implementations/RedisDatabase.cs +++ b/src/core/StackExchange.Redis.Extensions.Core/Implementations/RedisDatabase.cs @@ -116,6 +116,17 @@ public async Task GetAsync(string key, TimeSpan expiresIn, CommandFlags fl return result; } + /// + public async Task GetAsync(string key, Type returnType, CommandFlags flag = CommandFlags.None) + { + var valueBytes = await Database.StringGetAsync(key, flag).ConfigureAwait(false); + + if (!valueBytes.HasValue) + return default; + + return Serializer.Deserialize(valueBytes, returnType); + } + /// public Task AddAsync(string key, T value, When when = When.Always, CommandFlags flag = CommandFlags.None) { diff --git a/src/serializers/StackExchange.Redis.Extensions.Binary/BinarySerializer.cs b/src/serializers/StackExchange.Redis.Extensions.Binary/BinarySerializer.cs index 100bd812..6a25d836 100644 --- a/src/serializers/StackExchange.Redis.Extensions.Binary/BinarySerializer.cs +++ b/src/serializers/StackExchange.Redis.Extensions.Binary/BinarySerializer.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; using System.Runtime.Serialization.Formatters.Binary; using StackExchange.Redis.Extensions.Core; @@ -20,6 +21,14 @@ public T Deserialize(byte[] serializedObject) return (T)binaryFormatter.Deserialize(ms); } + /// + public object Deserialize(byte[] serializedObject, Type returnType) + { + using var ms = new MemoryStream(serializedObject); + + return binaryFormatter.Deserialize(ms); + } + /// public byte[] Serialize(object item) { diff --git a/src/serializers/StackExchange.Redis.Extensions.Jil/JilSerializer.cs b/src/serializers/StackExchange.Redis.Extensions.Jil/JilSerializer.cs index 1a8ac652..ebf18b45 100644 --- a/src/serializers/StackExchange.Redis.Extensions.Jil/JilSerializer.cs +++ b/src/serializers/StackExchange.Redis.Extensions.Jil/JilSerializer.cs @@ -53,5 +53,12 @@ public T Deserialize(byte[] serializedObject) var jsonString = encoding.GetString(serializedObject); return JSON.Deserialize(jsonString); } + + /// + public object Deserialize(byte[] serializedObject, Type returnType) + { + var jsonString = encoding.GetString(serializedObject); + return JSON.Deserialize(jsonString, returnType); + } } } diff --git a/src/serializers/StackExchange.Redis.Extensions.MsgPack/MsgPackObjectSerializer.cs b/src/serializers/StackExchange.Redis.Extensions.MsgPack/MsgPackObjectSerializer.cs index 5997a6ba..1eec7841 100644 --- a/src/serializers/StackExchange.Redis.Extensions.MsgPack/MsgPackObjectSerializer.cs +++ b/src/serializers/StackExchange.Redis.Extensions.MsgPack/MsgPackObjectSerializer.cs @@ -46,6 +46,21 @@ public T Deserialize(byte[] serializedObject) return serializer.Unpack(byteStream); } + /// + public object Deserialize(byte[] serializedObject, Type returnType) + { + if (returnType == typeof(string)) + { + return Convert.ChangeType(encoding.GetString(serializedObject), returnType); + } + + var serializer = MessagePackSerializer.Get(returnType); + + using var byteStream = new MemoryStream(serializedObject); + + return serializer.Unpack(byteStream); + } + /// public byte[] Serialize(object item) { diff --git a/src/serializers/StackExchange.Redis.Extensions.Newtonsoft/NewtonsoftSerializer.cs b/src/serializers/StackExchange.Redis.Extensions.Newtonsoft/NewtonsoftSerializer.cs index c0cfba47..842033e0 100644 --- a/src/serializers/StackExchange.Redis.Extensions.Newtonsoft/NewtonsoftSerializer.cs +++ b/src/serializers/StackExchange.Redis.Extensions.Newtonsoft/NewtonsoftSerializer.cs @@ -1,4 +1,5 @@ -using System.Text; +using System; +using System.Text; using Newtonsoft.Json; @@ -53,5 +54,12 @@ public T Deserialize(byte[] serializedObject) var jsonString = encoding.GetString(serializedObject); return JsonConvert.DeserializeObject(jsonString, settings); } + + /// + public object Deserialize(byte[] serializedObject, Type returnType) + { + var jsonString = encoding.GetString(serializedObject); + return JsonConvert.DeserializeObject(jsonString, returnType, settings); + } } } diff --git a/src/serializers/StackExchange.Redis.Extensions.Protobuf/ProtobufSerializer.cs b/src/serializers/StackExchange.Redis.Extensions.Protobuf/ProtobufSerializer.cs index 222b9c5b..57a4cbb3 100644 --- a/src/serializers/StackExchange.Redis.Extensions.Protobuf/ProtobufSerializer.cs +++ b/src/serializers/StackExchange.Redis.Extensions.Protobuf/ProtobufSerializer.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; using ProtoBuf; @@ -28,5 +29,13 @@ public T Deserialize(byte[] serializedObject) return Serializer.Deserialize(ms); } + + /// + public object Deserialize(byte[] serializedObject, Type returnType) + { + using var ms = new MemoryStream(serializedObject); + + return Serializer.Deserialize(returnType, ms); + } } } diff --git a/src/serializers/StackExchange.Redis.Extensions.System.Text.Json/SystemTextJsonSerializer.cs b/src/serializers/StackExchange.Redis.Extensions.System.Text.Json/SystemTextJsonSerializer.cs index 62677e4f..cd53ccd2 100644 --- a/src/serializers/StackExchange.Redis.Extensions.System.Text.Json/SystemTextJsonSerializer.cs +++ b/src/serializers/StackExchange.Redis.Extensions.System.Text.Json/SystemTextJsonSerializer.cs @@ -1,4 +1,5 @@ -using System.Text.Json; +using System; +using System.Text.Json; using StackExchange.Redis.Extensions.Core; @@ -20,5 +21,11 @@ public byte[] Serialize(object item) { return JsonSerializer.SerializeToUtf8Bytes(item, SerializationOptions.Flexible); } + + /// + public object Deserialize(byte[] serializedObject, Type returnType) + { + return JsonSerializer.Deserialize(serializedObject, returnType, SerializationOptions.Flexible); + } } } diff --git a/src/serializers/StackExchange.Redis.Extensions.Utf8Json/Utf8JsonSerializer.cs b/src/serializers/StackExchange.Redis.Extensions.Utf8Json/Utf8JsonSerializer.cs index 73b26c51..12ee4ee1 100644 --- a/src/serializers/StackExchange.Redis.Extensions.Utf8Json/Utf8JsonSerializer.cs +++ b/src/serializers/StackExchange.Redis.Extensions.Utf8Json/Utf8JsonSerializer.cs @@ -1,4 +1,5 @@ -using System.Text; +using System; +using System.Text; using System.Threading.Tasks; using StackExchange.Redis.Extensions.Core; @@ -28,5 +29,11 @@ public T Deserialize(byte[] serializedObject) { return global::Utf8Json.JsonSerializer.Deserialize(serializedObject); } + + /// + public object Deserialize(byte[] serializedObject, Type returnType) + { + return global::Utf8Json.JsonSerializer.NonGeneric.Deserialize(returnType, serializedObject); + } } } diff --git a/tests/StackExchange.Redis.Extensions.Core.Tests/CacheClientTestBase.cs b/tests/StackExchange.Redis.Extensions.Core.Tests/CacheClientTestBase.cs index bf39201c..7b05730e 100644 --- a/tests/StackExchange.Redis.Extensions.Core.Tests/CacheClientTestBase.cs +++ b/tests/StackExchange.Redis.Extensions.Core.Tests/CacheClientTestBase.cs @@ -8,9 +8,11 @@ using Moq; +using StackExchange.Redis.Extensions.Binary; using StackExchange.Redis.Extensions.Core.Abstractions; using StackExchange.Redis.Extensions.Core.Configuration; using StackExchange.Redis.Extensions.Core.Implementations; +using StackExchange.Redis.Extensions.Protobuf; using StackExchange.Redis.Extensions.Tests.Extensions; using StackExchange.Redis.Extensions.Tests.Helpers; @@ -536,6 +538,53 @@ public async Task Adding_Value_Type_Should_Return_Correct_Value() Assert.Equal(dbValue, d); } + [Fact] + public async Task Adding_Value_Type_Should_Return_Non_Generic_Correct_Value() + { + var d = new TestClass { Key = $"key21", Value = "value21" }; + var added = await Sut.GetDbFromConfiguration().AddAsync("my Key", d); + + // TODO: Assuming that only the type of TestClass can be obtained here. + var returnType = typeof(TestClass); + + // TODO: Use non-generic methods to get results. + var dbValue = await Sut.GetDbFromConfiguration().GetAsync("my Key", returnType); + Assert.True(added); + Assert.True(db.KeyExists("my Key")); + + // TODO: dbValue equal. + Assert.Equal(dbValue, d); + } + + [Fact] + public async Task Adding_Value_Type_Validate_Generic_Return_Object() + { + var d = new TestClass { Key = $"key21", Value = "value21" }; + var added = await Sut.GetDbFromConfiguration().AddAsync("my Key", d); + Assert.True(added); + Assert.True(db.KeyExists("my Key")); + if (Sut.GetDbFromConfiguration().Serializer is ProtobufSerializer) + { + // TODO: ProtobufSerializer generic get object throws an ArgumentNullException. + await Assert.ThrowsAsync(() => Sut.GetDbFromConfiguration().GetAsync("my Key")); + } + else + { + // TODO: Use generic methods to get results. + var dbValue = await Sut.GetDbFromConfiguration().GetAsync("my Key"); + if (Sut.GetDbFromConfiguration().Serializer is BinarySerializer) + { + // TODO: BinarySerializer dbValue equal. + Assert.Equal(dbValue, d); + } + else + { + // TODO: dbValue not equal. + Assert.NotEqual(dbValue, d); + } + } + } + [Fact] public async Task Adding_Collection_To_Redis_Should_Work_Correctly() {