diff --git a/Enyim.Caching/Configuration/MemcachedClientConfiguration.cs b/Enyim.Caching/Configuration/MemcachedClientConfiguration.cs index 4feed331..edc5d150 100755 --- a/Enyim.Caching/Configuration/MemcachedClientConfiguration.cs +++ b/Enyim.Caching/Configuration/MemcachedClientConfiguration.cs @@ -125,9 +125,24 @@ public MemcachedClientConfiguration( NodeLocator = options.Servers.Count > 1 ? typeof(DefaultNodeLocator) : typeof(SingleNodeLocator); } - if(options.Transcoder != null) + if(!string.IsNullOrEmpty(options.Transcoder)) { - _transcoder = options.Transcoder; + try + { + if (options.Transcoder == "BinaryFormatterTranscoder") + options.Transcoder = "Enyim.Caching.Memcached.Transcoders.BinaryFormatterTranscoder"; + + var transcoderType = Type.GetType(options.Transcoder); + if (transcoderType != null) + { + Transcoder = Activator.CreateInstance(transcoderType) as ITranscoder; + _logger.LogDebug($"Use '{options.Transcoder}'"); + } + } + catch (Exception ex) + { + _logger.LogError(new EventId(), ex, $"Unable to load '{options.Transcoder}'"); + } } if (options.NodeLocatorFactory != null) diff --git a/Enyim.Caching/Configuration/MemcachedClientOptions.cs b/Enyim.Caching/Configuration/MemcachedClientOptions.cs index 0fc7b45d..0864e04c 100644 --- a/Enyim.Caching/Configuration/MemcachedClientOptions.cs +++ b/Enyim.Caching/Configuration/MemcachedClientOptions.cs @@ -19,7 +19,7 @@ public class MemcachedClientOptions : IOptions public string KeyTransformer { get; set; } - public ITranscoder Transcoder { get; set; } + public string Transcoder { get; set; } public IProviderFactory NodeLocatorFactory { get; set; } diff --git a/Enyim.Caching/Memcached/Transcoders/BinaryFormatterTranscoder.cs b/Enyim.Caching/Memcached/Transcoders/BinaryFormatterTranscoder.cs new file mode 100644 index 00000000..460f85bd --- /dev/null +++ b/Enyim.Caching/Memcached/Transcoders/BinaryFormatterTranscoder.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; +using System.Text; + +namespace Enyim.Caching.Memcached.Transcoders +{ + public class BinaryFormatterTranscoder : DefaultTranscoder + { + protected override ArraySegment SerializeObject(object value) + { + using (var ms = new MemoryStream()) + { + new BinaryFormatter().Serialize(ms, value); + return new ArraySegment(ms.GetBuffer(), 0, (int)ms.Length); + } + } + + public override T Deserialize(CacheItem item) + { + return (T)base.Deserialize(item); + } + + protected override object DeserializeObject(ArraySegment value) + { + using (var ms = new MemoryStream(value.Array, value.Offset, value.Count)) + { + return new BinaryFormatter().Deserialize(ms); + } + } + } +} diff --git a/Enyim.Caching/Memcached/Transcoders/DefaultTranscoder.cs b/Enyim.Caching/Memcached/Transcoders/DefaultTranscoder.cs index 83fdca95..c73a35af 100755 --- a/Enyim.Caching/Memcached/Transcoders/DefaultTranscoder.cs +++ b/Enyim.Caching/Memcached/Transcoders/DefaultTranscoder.cs @@ -28,7 +28,7 @@ object ITranscoder.Deserialize(CacheItem item) return this.Deserialize(item); } - T ITranscoder.Deserialize(CacheItem item) + public virtual T Deserialize(CacheItem item) { if (item.Data == null || item.Data.Count == 0) return default(T); @@ -184,7 +184,7 @@ protected virtual object Deserialize(CacheItem item) // earlier versions serialized decimals with TypeCode.Decimal // even though they were saved by BinaryFormatter case TypeCode.Decimal: - //case TypeCode.Object: return this.DeserializeObject(data); + case TypeCode.Object: return this.DeserializeObject(data); default: throw new InvalidOperationException("Unknown TypeCode was returned: " + code); } } diff --git a/MemcachedTest/MemcachedClientTest.cs b/MemcachedTest/MemcachedClientTest.cs index 9b5c5bd8..6bdd73b4 100755 --- a/MemcachedTest/MemcachedClientTest.cs +++ b/MemcachedTest/MemcachedClientTest.cs @@ -19,21 +19,27 @@ public abstract class MemcachedClientTest private static readonly Enyim.Caching.ILog log = Enyim.Caching.LogManager.GetLogger(typeof(MemcachedClientTest)); public const string TestObjectKey = "Hello_World"; - protected virtual MemcachedClient GetClient(MemcachedProtocol protocol = MemcachedProtocol.Binary) + protected virtual MemcachedClient GetClient(MemcachedProtocol protocol = MemcachedProtocol.Binary, bool useBinaryFormatterTranscoder = false) { IServiceCollection services = new ServiceCollection(); services.AddEnyimMemcached(options => { options.AddServer("memcached", 11211); options.Protocol = protocol; + if (useBinaryFormatterTranscoder) + { + options.Transcoder = "BinaryFormatterTranscoder"; + } }); - services.AddLogging(); + services.AddLogging(builder => builder.SetMinimumLevel(LogLevel.Error).AddConsole()); + IServiceProvider serviceProvider = services.BuildServiceProvider(); var client = serviceProvider.GetService() as MemcachedClient; client.Remove("VALUE"); return client; } + [Serializable]// This attribute is for BinaryFormatterTranscoder public class TestData { public TestData() { } @@ -60,6 +66,11 @@ public async Task StoreObjectTest() { Assert.True(await client.StoreAsync(StoreMode.Set, TestObjectKey, td, DateTime.Now.AddSeconds(5))); } + + using (MemcachedClient client = GetClient(MemcachedProtocol.Binary, true)) + { + Assert.True(await client.StoreAsync(StoreMode.Set, TestObjectKey, td, DateTime.Now.AddSeconds(5))); + } } [Fact] @@ -83,6 +94,18 @@ public void GetObjectTest() Assert.Equal(td2.FieldC, 19810619); Assert.True(td2.FieldD, "Object was corrupted."); } + + using (MemcachedClient client = GetClient(MemcachedProtocol.Binary, true)) + { + Assert.True(client.Store(StoreMode.Set, TestObjectKey, td), "Initialization failed."); + TestData td2 = client.Get(TestObjectKey); + + Assert.NotNull(td2); + Assert.Equal(td2.FieldA, "Hello"); + Assert.Equal(td2.FieldB, "World"); + Assert.Equal(td2.FieldC, 19810619); + Assert.True(td2.FieldD, "Object was corrupted."); + } } [Fact] diff --git a/MemcachedTest/MemcachedTest.csproj b/MemcachedTest/MemcachedTest.csproj index c42cfaa8..4fd5a9aa 100755 --- a/MemcachedTest/MemcachedTest.csproj +++ b/MemcachedTest/MemcachedTest.csproj @@ -6,6 +6,7 @@ + diff --git a/SampleWebApp/appsettings.json b/SampleWebApp/appsettings.json index 17352821..bd107408 100644 --- a/SampleWebApp/appsettings.json +++ b/SampleWebApp/appsettings.json @@ -13,7 +13,8 @@ "receiveTimeout": "00:00:15", "deadTimeout": "00:00:15", "queueTimeout": "00:00:00.150" - } + }//, + //"Transcoder": "BinaryFormatterTranscoder" //, //"KeyTransformer": "Enyim.Caching.Memcached.SHA1KeyTransformer" //,