Skip to content

Commit 4c30f82

Browse files
Merge pull request #470 from johelvisguzman/issue419
Added a new memcached caching provider
2 parents cf66ea5 + f86f5c7 commit 4c30f82

25 files changed

+670
-17
lines changed

DotNetToolkit.Repository.sln

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.Te
1313
EndProject
1414
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.EntityFramework", "src\DotNetToolkit.Repository.EntityFramework\DotNetToolkit.Repository.EntityFramework.csproj", "{8DBCF7DE-532D-45DF-A6B8-5D89415C5B77}"
1515
EndProject
16-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.Integration.Test", "test\DotNetToolkit.Repository.Integration.Test\DotNetToolkit.Repository.Integration.Test.csproj", "{2F99B66F-A347-4E8D-8ACA-5A34246A1FA6}"
17-
EndProject
1816
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.EntityFrameworkCore", "src\DotNetToolkit.Repository.EntityFrameworkCore\DotNetToolkit.Repository.EntityFrameworkCore.csproj", "{0A9D9AA4-F01C-470F-AD5B-5A81EA7A398D}"
1917
EndProject
2018
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.AdoNet", "src\DotNetToolkit.Repository.AdoNet\DotNetToolkit.Repository.AdoNet.csproj", "{77973BF2-E352-43C9-8CF2-99E01142B2A8}"
@@ -43,6 +41,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.Ca
4341
EndProject
4442
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.Caching.Redis", "src\DotNetToolkit.Repository.Caching.Redis\DotNetToolkit.Repository.Caching.Redis.csproj", "{445F6C84-FF28-4243-8148-DAB5A4813F93}"
4543
EndProject
44+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.Integration.Test", "test\DotNetToolkit.Repository.Integration.Test\DotNetToolkit.Repository.Integration.Test.csproj", "{C895B8F4-5083-4D97-A1E6-D7DF01BDBE9D}"
45+
EndProject
46+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.Caching.Memcached", "src\DotNetToolkit.Repository.Caching.Memcached\DotNetToolkit.Repository.Caching.Memcached.csproj", "{421F9CC1-9A5F-4F3D-A851-AB72958A4E96}"
47+
EndProject
4648
Global
4749
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4850
Debug|Any CPU = Debug|Any CPU
@@ -61,10 +63,6 @@ Global
6163
{8DBCF7DE-532D-45DF-A6B8-5D89415C5B77}.Debug|Any CPU.Build.0 = Debug|Any CPU
6264
{8DBCF7DE-532D-45DF-A6B8-5D89415C5B77}.Release|Any CPU.ActiveCfg = Release|Any CPU
6365
{8DBCF7DE-532D-45DF-A6B8-5D89415C5B77}.Release|Any CPU.Build.0 = Release|Any CPU
64-
{2F99B66F-A347-4E8D-8ACA-5A34246A1FA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
65-
{2F99B66F-A347-4E8D-8ACA-5A34246A1FA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
66-
{2F99B66F-A347-4E8D-8ACA-5A34246A1FA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
67-
{2F99B66F-A347-4E8D-8ACA-5A34246A1FA6}.Release|Any CPU.Build.0 = Release|Any CPU
6866
{0A9D9AA4-F01C-470F-AD5B-5A81EA7A398D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
6967
{0A9D9AA4-F01C-470F-AD5B-5A81EA7A398D}.Debug|Any CPU.Build.0 = Debug|Any CPU
7068
{0A9D9AA4-F01C-470F-AD5B-5A81EA7A398D}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -112,6 +110,14 @@ Global
112110
{445F6C84-FF28-4243-8148-DAB5A4813F93}.Debug|Any CPU.Build.0 = Debug|Any CPU
113111
{445F6C84-FF28-4243-8148-DAB5A4813F93}.Release|Any CPU.ActiveCfg = Release|Any CPU
114112
{445F6C84-FF28-4243-8148-DAB5A4813F93}.Release|Any CPU.Build.0 = Release|Any CPU
113+
{C895B8F4-5083-4D97-A1E6-D7DF01BDBE9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
114+
{C895B8F4-5083-4D97-A1E6-D7DF01BDBE9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
115+
{C895B8F4-5083-4D97-A1E6-D7DF01BDBE9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
116+
{C895B8F4-5083-4D97-A1E6-D7DF01BDBE9D}.Release|Any CPU.Build.0 = Release|Any CPU
117+
{421F9CC1-9A5F-4F3D-A851-AB72958A4E96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
118+
{421F9CC1-9A5F-4F3D-A851-AB72958A4E96}.Debug|Any CPU.Build.0 = Debug|Any CPU
119+
{421F9CC1-9A5F-4F3D-A851-AB72958A4E96}.Release|Any CPU.ActiveCfg = Release|Any CPU
120+
{421F9CC1-9A5F-4F3D-A851-AB72958A4E96}.Release|Any CPU.Build.0 = Release|Any CPU
115121
EndGlobalSection
116122
GlobalSection(SolutionProperties) = preSolution
117123
HideSolutionNode = FALSE
@@ -120,7 +126,6 @@ Global
120126
{76BC5AB7-1198-4C99-B2C3-3B734931F8EE} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
121127
{EAE7B507-D908-4650-A301-C3341F005A51} = {DAB3DD1E-AD99-46C9-AC42-07E2F03D5A06}
122128
{8DBCF7DE-532D-45DF-A6B8-5D89415C5B77} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
123-
{2F99B66F-A347-4E8D-8ACA-5A34246A1FA6} = {DAB3DD1E-AD99-46C9-AC42-07E2F03D5A06}
124129
{0A9D9AA4-F01C-470F-AD5B-5A81EA7A398D} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
125130
{77973BF2-E352-43C9-8CF2-99E01142B2A8} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
126131
{14409451-ED11-4DEF-8A89-783834F8316C} = {257E837B-5B99-44D7-9647-1C2FE0A07520}
@@ -133,6 +138,8 @@ Global
133138
{32262A29-A96F-423B-BA97-F7E2F79FAB16} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
134139
{75757CCF-9F6E-433A-885E-F92DE12FFB51} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
135140
{445F6C84-FF28-4243-8148-DAB5A4813F93} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
141+
{C895B8F4-5083-4D97-A1E6-D7DF01BDBE9D} = {DAB3DD1E-AD99-46C9-AC42-07E2F03D5A06}
142+
{421F9CC1-9A5F-4F3D-A851-AB72958A4E96} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
136143
EndGlobalSection
137144
GlobalSection(ExtensibilityGlobals) = postSolution
138145
SolutionGuid = {96973E0C-81D1-42DE-9F78-7103241B4E07}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ If you want to use DotNetToolkit.Repository for the first time, the [Getting Sta
2828
[DotNetToolkit.Repository.Extensions.Unity](https://www.nuget.org/packages/DotNetToolkit.Repository.Extensions.Unity/) | [![DotNetToolkit.Repository.Extensions.Unity](https://img.shields.io/nuget/v/DotNetToolkit.Repository.Extensions.Unity.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Extensions.Unity/) | [![DotNetToolkit.Repository.Extensions.Unity](https://img.shields.io/nuget/dt/DotNetToolkit.Repository.Extensions.Unity.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Extensions.Unity/) | [![MyGet (dev)](https://img.shields.io/myget/dotnettoolkitrepositorydev/v/DotNetToolkit.Repository.Extensions.Unity.svg)](https://www.myget.org/feed/dotnettoolkitrepositorydev/package/nuget/DotNetToolkit.Repository.Extensions.Unity) |
2929
[DotNetToolkit.Repository.Caching.InMemory](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.InMemory/) | [![DotNetToolkit.Repository.Caching.InMemory](https://img.shields.io/nuget/v/DotNetToolkit.Repository.Caching.InMemory.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.InMemory/) | [![DotNetToolkit.Repository.Caching.InMemory](https://img.shields.io/nuget/dt/DotNetToolkit.Repository.Caching.InMemory.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.InMemory/) | [![MyGet (dev)](https://img.shields.io/myget/dotnettoolkitrepositorydev/v/DotNetToolkit.Repository.Caching.InMemory.svg)](https://www.myget.org/feed/dotnettoolkitrepositorydev/package/nuget/DotNetToolkit.Repository.Caching.InMemory) |
3030
[DotNetToolkit.Repository.Caching.Redis](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.Redis/) | [![DotNetToolkit.Repository.Caching.Redis](https://img.shields.io/nuget/v/DotNetToolkit.Repository.Caching.Redis.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.Redis/) | [![DotNetToolkit.Repository.Caching.Redis](https://img.shields.io/nuget/dt/DotNetToolkit.Repository.Caching.Redis.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.Redis/) | [![MyGet (dev)](https://img.shields.io/myget/dotnettoolkitrepositorydev/v/DotNetToolkit.Repository.Caching.Redis.svg)](https://www.myget.org/feed/dotnettoolkitrepositorydev/package/nuget/DotNetToolkit.Repository.Caching.Redis) |
31+
[DotNetToolkit.Repository.Caching.Memcached](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.Memcached/) | [![DotNetToolkit.Repository.Caching.Memcached](https://img.shields.io/nuget/v/DotNetToolkit.Repository.Caching.Memcached.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.Memcached/) | [![DotNetToolkit.Repository.Caching.Memcached](https://img.shields.io/nuget/dt/DotNetToolkit.Repository.Caching.Memcached.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.Memcached/) | [![MyGet (dev)](https://img.shields.io/myget/dotnettoolkitrepositorydev/v/DotNetToolkit.Repository.Caching.Memcached.svg)](https://www.myget.org/feed/dotnettoolkitrepositorydev/package/nuget/DotNetToolkit.Repository.Caching.Memcached) |
3132

3233
## Features
3334

appveyor.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ after_build:
6262
- dotnet pack .\src\DotNetToolkit.Repository.Extensions.Unity\DotNetToolkit.Repository.Extensions.Unity.csproj --configuration Release
6363
- dotnet pack .\src\DotNetToolkit.Repository.Caching.InMemory\DotNetToolkit.Repository.Caching.InMemory.csproj --configuration Release
6464
- dotnet pack .\src\DotNetToolkit.Repository.Caching.Redis\DotNetToolkit.Repository.Caching.Redis.csproj --configuration Release
65+
- dotnet pack .\src\DotNetToolkit.Repository.Caching.Memcached\DotNetToolkit.Repository.Caching.Memcached.csproj --configuration Release
6566

6667
#---------------------------------#
6768
# artifacts configuration #

src/DotNetToolkit.Repository.Caching.InMemory/InMemoryCache.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public int Increment([NotNull] string key, int defaultValue, int incrementValue)
121121

122122
#endregion
123123

124-
#region Implementation of ICache
124+
#region Implementation of IDisposable
125125

126126
/// <summary>
127127
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<Import Project="..\..\build\common.props" />
4+
5+
<PropertyGroup>
6+
<TargetFramework>net451</TargetFramework>
7+
<Description>A caching provider for Enyim Memcached Client.</Description>
8+
<AssemblyName>DotNetToolkit.Repository.Caching.Memcached</AssemblyName>
9+
<RootNamespace>DotNetToolkit.Repository.Caching.Memcached</RootNamespace>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="EnyimMemcached" Version="2.16.0" />
14+
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<ProjectReference Include="..\DotNetToolkit.Repository\DotNetToolkit.Repository.csproj" />
19+
</ItemGroup>
20+
21+
</Project>
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
namespace DotNetToolkit.Repository.Caching.Memcached
2+
{
3+
using Configuration.Caching;
4+
using Enyim.Caching;
5+
using Enyim.Caching.Configuration;
6+
using Enyim.Caching.Memcached;
7+
using JetBrains.Annotations;
8+
using Newtonsoft.Json;
9+
using System;
10+
using Utility;
11+
12+
/// <summary>
13+
/// An implementation of <see cref="ICache" />.
14+
/// </summary>
15+
public class MemcachedCache : ICache
16+
{
17+
#region Properties
18+
19+
/// <summary>
20+
/// Gets the memcached client.
21+
/// </summary>
22+
public IMemcachedClient Client { get; }
23+
24+
#endregion
25+
26+
#region Constructors
27+
28+
/// <summary>
29+
/// Initializes a new instance of the <see cref="MemcachedCache" /> class using the default configuration section (enyim/memcached).
30+
/// </summary>
31+
public MemcachedCache()
32+
{
33+
Client = new MemcachedClient();
34+
}
35+
36+
/// <summary>
37+
/// Initializes a new instance of the <see cref="MemcachedCache" /> class using the specified configuration section.
38+
/// </summary>
39+
/// <param name="sectionName">The name of the configuration section to be used for configuring the behavior of the client.</param>
40+
public MemcachedCache([NotNull] string sectionName)
41+
{
42+
Client = new MemcachedClient(Guard.NotEmpty(sectionName, nameof(sectionName)));
43+
}
44+
45+
/// <summary>
46+
/// Initializes a new instance of the <see cref="MemcachedCache" /> class using the specified client.
47+
/// </summary>
48+
/// <param name="client">The memcached client.</param>
49+
public MemcachedCache([NotNull] IMemcachedClient client)
50+
{
51+
Client = Guard.NotNull(client, nameof(client));
52+
}
53+
54+
/// <summary>
55+
/// Initializes a new instance of the <see cref="MemcachedCache" /> class.
56+
/// </summary>
57+
/// <param name="configuration">The configuration to use for the memcached client.</param>
58+
public MemcachedCache([NotNull] IMemcachedClientConfiguration configuration)
59+
{
60+
Client = new MemcachedClient(Guard.NotNull(configuration, nameof(configuration)));
61+
}
62+
63+
/// <summary>
64+
/// Initializes a new instance of the <see cref="MemcachedCache" /> class.
65+
/// </summary>
66+
/// <param name="host">The host name.</param>
67+
/// <param name="port">The port.</param>
68+
/// <param name="protocol">The type of the communication between client and server.</param>
69+
public MemcachedCache([NotNull] string host, int port, MemcachedProtocol protocol)
70+
{
71+
Guard.NotEmpty(host, nameof(host));
72+
73+
var config = new MemcachedClientConfiguration();
74+
75+
config.AddServer(host, port);
76+
config.Protocol = protocol;
77+
78+
Client = new MemcachedClient(config);
79+
}
80+
81+
/// <summary>
82+
/// Initializes a new instance of the <see cref="MemcachedCache" /> class.
83+
/// </summary>
84+
/// <param name="host">The host name.</param>
85+
/// <param name="port">The port.</param>
86+
/// <param name="username">The username to use to authenticate with the server.</param>
87+
/// <param name="password">The password to use to authenticate with the server.</param>
88+
/// <param name="protocol">The type of the communication between client and server.</param>
89+
public MemcachedCache([NotNull] string host, int port, [NotNull] string username, [NotNull] string password, MemcachedProtocol protocol)
90+
{
91+
Guard.NotEmpty(host, nameof(host));
92+
Guard.NotEmpty(username, nameof(username));
93+
Guard.NotEmpty(password, nameof(password));
94+
95+
var config = new MemcachedClientConfiguration();
96+
97+
config.AddServer(host, port);
98+
config.Protocol = protocol;
99+
config.Authentication.Type = typeof(PlainTextAuthenticator);
100+
config.Authentication.Parameters["userName"] = username;
101+
config.Authentication.Parameters["password"] = password;
102+
103+
Client = new MemcachedClient(config);
104+
}
105+
106+
#endregion
107+
108+
#region Private Methods
109+
110+
private static string Serialize(object o)
111+
{
112+
if (o == null)
113+
return null;
114+
115+
return JsonConvert.SerializeObject(o);
116+
}
117+
118+
private static T Deserialize<T>(string v)
119+
{
120+
if (string.IsNullOrEmpty(v))
121+
return default(T);
122+
123+
return JsonConvert.DeserializeObject<T>(v);
124+
}
125+
126+
#endregion
127+
128+
#region Implementation of ICache
129+
130+
/// <summary>
131+
/// Create or overwrite an entry in the cache.
132+
/// </summary>
133+
/// <typeparam name="T">The type of the cache value.</typeparam>
134+
/// <param name="key">An object identifying the entry.</param>
135+
/// <param name="value">The value to cache.</param>
136+
/// <param name="expiry">The cache expiration time.</param>
137+
/// <param name="cacheRemovedCallback">A callback function for a value is removed from the cache.</param>
138+
public void Set<T>([NotNull] string key, [CanBeNull] T value, [CanBeNull] TimeSpan? expiry, [CanBeNull] Action<string> cacheRemovedCallback = null)
139+
{
140+
Guard.NotEmpty(key, nameof(key));
141+
142+
if (expiry.HasValue)
143+
{
144+
Client.Store(StoreMode.Set, key, Serialize(value), expiry.Value);
145+
}
146+
else
147+
{
148+
Client.Store(StoreMode.Set, key, Serialize(value));
149+
}
150+
}
151+
152+
/// <summary>
153+
/// Removes the object associated with the given key.
154+
/// </summary>
155+
/// <param name="key">An object identifying the entry.</param>
156+
public void Remove([NotNull] string key)
157+
{
158+
Client.Remove(Guard.NotEmpty(key, nameof(key)));
159+
}
160+
161+
/// <summary>
162+
/// Gets the item associated with this key if present.
163+
/// </summary>
164+
/// <typeparam name="T">The type of the cache value.</typeparam>
165+
/// <param name="key">An object identifying the requested entry.</param>
166+
/// <param name="value">The object found in the cache.</param>
167+
/// <returns>c<c>true</c> if the an object was found with the specified key; otherwise, <c>false</c>.</returns>
168+
public bool TryGetValue<T>(string key, out T value)
169+
{
170+
try
171+
{
172+
value = Deserialize<T>(Client.Get<string>(Guard.NotEmpty(key, nameof(key))));
173+
174+
if (Equals(value, default(T)))
175+
{
176+
value = default(T);
177+
178+
return false;
179+
}
180+
}
181+
catch
182+
{
183+
value = default(T);
184+
185+
return false;
186+
}
187+
188+
return true;
189+
}
190+
191+
/// <summary>
192+
/// Increments the number stored at key by one
193+
/// </summary>
194+
/// <param name="key">The key.</param>
195+
/// <param name="defaultValue">The default value.</param>
196+
/// <param name="incrementValue">The increment value.</param>
197+
/// <returns>The value of key after the increment.</returns>
198+
public int Increment(string key, int defaultValue, int incrementValue)
199+
{
200+
Guard.NotEmpty(key, nameof(key));
201+
202+
var value = Client.Increment(key, Convert.ToUInt64(defaultValue), Convert.ToUInt64(incrementValue));
203+
204+
return Convert.ToInt32(value);
205+
}
206+
207+
#endregion
208+
209+
#region Implementation of IDisposable
210+
211+
/// <summary>
212+
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
213+
/// </summary>
214+
public void Dispose()
215+
{
216+
Client.Dispose();
217+
}
218+
219+
#endregion
220+
}
221+
}

0 commit comments

Comments
 (0)