Skip to content

Commit

Permalink
✨ First Edition of HybridCachingProvider.
Browse files Browse the repository at this point in the history
  • Loading branch information
catcherwong committed Jan 21, 2018
1 parent e4ab66d commit 3aa72e2
Show file tree
Hide file tree
Showing 12 changed files with 446 additions and 41 deletions.
7 changes: 7 additions & 0 deletions EasyCaching.sln
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyCaching.Demo.Intercepto
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyCaching.Demo.Interceptor.AspectCore", "sample\EasyCaching.Demo.Interceptor.AspectCore\EasyCaching.Demo.Interceptor.AspectCore.csproj", "{36D12667-E5C2-4C91-A450-A070DE07A3E6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyCaching.HybridCache", "src\EasyCaching.HybridCache\EasyCaching.HybridCache.csproj", "{013F6582-CF26-4F5A-BE0B-B383347CF656}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -115,6 +117,10 @@ Global
{36D12667-E5C2-4C91-A450-A070DE07A3E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{36D12667-E5C2-4C91-A450-A070DE07A3E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{36D12667-E5C2-4C91-A450-A070DE07A3E6}.Release|Any CPU.Build.0 = Release|Any CPU
{013F6582-CF26-4F5A-BE0B-B383347CF656}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{013F6582-CF26-4F5A-BE0B-B383347CF656}.Debug|Any CPU.Build.0 = Debug|Any CPU
{013F6582-CF26-4F5A-BE0B-B383347CF656}.Release|Any CPU.ActiveCfg = Release|Any CPU
{013F6582-CF26-4F5A-BE0B-B383347CF656}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{CE61FAA2-0233-451C-991D-4222ED61C84B} = {A0F5CC7E-155F-4726-8DEB-E966950B3FE9}
Expand All @@ -134,5 +140,6 @@ Global
{7B55B6D9-4221-4E82-AED6-BEC9A60C99D2} = {A0F5CC7E-155F-4726-8DEB-E966950B3FE9}
{C343BF4C-F025-4DB6-8A9B-DE8B12DCCAAE} = {F88D727A-9F9C-43D9-90B1-D4A02BF8BC98}
{36D12667-E5C2-4C91-A450-A070DE07A3E6} = {F88D727A-9F9C-43D9-90B1-D4A02BF8BC98}
{013F6582-CF26-4F5A-BE0B-B383347CF656} = {A0F5CC7E-155F-4726-8DEB-E966950B3FE9}
EndGlobalSection
EndGlobal
12 changes: 12 additions & 0 deletions src/EasyCaching.Core/EasyCachingMessage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
namespace EasyCaching.Core
{
public class EasyCachingMessage
{
public string CacheKey { get; set; }

public object CacheValue { get; set; }

public TimeSpan Expiration { get; set; }
}
}
4 changes: 2 additions & 2 deletions src/EasyCaching.Core/IEasyCachingPublisher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public interface IEasyCachingPublisher
/// <param name="cacheKey">Cache key.</param>
/// <param name="cacheValue">Cache value.</param>
/// <param name="expiration">Expiration.</param>
void Publish(string channel, string cacheKey, object cacheValue, TimeSpan expiration);
void Publish<T>(string channel, string cacheKey, T cacheValue, TimeSpan expiration);

/// <summary>
/// Publishs the async.
Expand All @@ -27,6 +27,6 @@ public interface IEasyCachingPublisher
/// <param name="cacheKey">Cache key.</param>
/// <param name="cacheValue">Cache value.</param>
/// <param name="expiration">Expiration.</param>
Task PublishAsync(string channel, string cacheKey, object cacheValue, TimeSpan expiration);
Task PublishAsync<T>(string channel, string cacheKey, T cacheValue, TimeSpan expiration);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
namespace EasyCaching.Core.Internal
{
{
using System.Collections.Generic;

/// <summary>
/// Redis cache options.
/// Base redis options.
/// </summary>
public class RedisCacheOptions
public class BaseRedisOptions
{
/// <summary>
/// Gets or sets the password to be used to connect to the Redis server.
Expand Down Expand Up @@ -47,13 +47,5 @@ public class RedisCacheOptions
/// The endpoints.
/// </value>
public IList<ServerEndPoint> Endpoints { get; } = new List<ServerEndPoint>();

/// <summary>
/// Gets or sets the Redis database index the cache will use.
/// </summary>
/// <value>
/// The database.
/// </value>
public int Database { get; set; } = 0;
}
}
13 changes: 13 additions & 0 deletions src/EasyCaching.HybridCache/EasyCaching.HybridCache.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\EasyCaching.Core\EasyCaching.Core.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="4.6.2" />
</ItemGroup>
</Project>
294 changes: 294 additions & 0 deletions src/EasyCaching.HybridCache/HybridCachingProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
namespace EasyCaching.HybridCache
{
using Autofac;
using EasyCaching.Core;
using EasyCaching.Core.Internal;
using System;
using System.Threading.Tasks;

/// <summary>
/// Hybrid caching provider.
/// </summary>
public interface IHybridCachingProvider : IEasyCachingProvider{}

/// <summary>
/// Hybrid caching provider.
/// </summary>
public class HybridCachingProvider : IHybridCachingProvider
{
/// <summary>
/// The local caching provider.
/// </summary>
private IEasyCachingProvider _localCachingProvider;

/// <summary>
/// The distributed caching provider.
/// </summary>
private IEasyCachingProvider _distributedCachingProvider;

/// <summary>
/// Initializes a new instance of the <see cref="T:EasyCaching.HybridCache.HybridCachingProvider"/> class.
/// </summary>
/// <param name="context">Context.</param>
public HybridCachingProvider(IComponentContext context)
{
this._localCachingProvider = context.ResolveKeyed<IEasyCachingProvider>("Local");
this._distributedCachingProvider = context.ResolveKeyed<IEasyCachingProvider>("Distributed");
}

/// <summary>
/// Gets a value indicating whether this <see cref="T:EasyCaching.HybridCache.HybridCachingProvider"/> is
/// distributed cache.
/// </summary>
/// <value><c>true</c> if is distributed cache; otherwise, <c>false</c>.</value>
public bool IsDistributedCache => true;

/// <summary>
/// Exists the specified cacheKey.
/// </summary>
/// <returns>The exists.</returns>
/// <param name="cacheKey">Cache key.</param>
public bool Exists(string cacheKey)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey,nameof(cacheKey));

var flag = false;

flag = _localCachingProvider.Exists(cacheKey);

if(!flag)
{
flag = _distributedCachingProvider.Exists(cacheKey);
}

return flag;
}

/// <summary>
/// Existses the specified cacheKey async.
/// </summary>
/// <returns>The async.</returns>
/// <param name="cacheKey">Cache key.</param>
public async Task<bool> ExistsAsync(string cacheKey)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));

var flag = false;

flag = await _localCachingProvider.ExistsAsync(cacheKey);

if (!flag)
{
flag = await _distributedCachingProvider.ExistsAsync(cacheKey);
}

return flag;
}

/// <summary>
/// Get the specified cacheKey, dataRetriever and expiration.
/// </summary>
/// <returns>The get.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="dataRetriever">Data retriever.</param>
/// <param name="expiration">Expiration.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public CacheValue<T> Get<T>(string cacheKey, Func<T> dataRetriever, TimeSpan expiration) where T : class
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

var value = _localCachingProvider.Get<T>(cacheKey);

if (value.HasValue)
{
return value;
}

value = _distributedCachingProvider.Get<T>(cacheKey);

if (value.HasValue)
{
return value;
}

var item = dataRetriever?.Invoke();
if (item != null)
{
Set(cacheKey, item, expiration);
return new CacheValue<T>(item, true);
}
else
{
//TODO : Set a null value to cache!!

return CacheValue<T>.NoValue;
}
}

/// <summary>
/// Get the specified cacheKey.
/// </summary>
/// <returns>The get.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public CacheValue<T> Get<T>(string cacheKey) where T : class
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));

var value = _localCachingProvider.Get<T>(cacheKey);

if (value.HasValue)
{
return value;
}

value = _distributedCachingProvider.Get<T>(cacheKey);

if (value.HasValue)
{
return value;
}
else
{
//TODO : Set a null value to cache!!

return CacheValue<T>.NoValue;
}
}

/// <summary>
/// Gets the specified cacheKey, dataRetriever and expiration async.
/// </summary>
/// <returns>The async.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="dataRetriever">Data retriever.</param>
/// <param name="expiration">Expiration.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public async Task<CacheValue<T>> GetAsync<T>(string cacheKey, Func<Task<T>> dataRetriever, TimeSpan expiration) where T : class
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

var value = await _localCachingProvider.GetAsync<T>(cacheKey);

if (value.HasValue)
{
return value;
}

value = await _distributedCachingProvider.GetAsync<T>(cacheKey);

if (value.HasValue)
{
return value;
}

var item = await dataRetriever?.Invoke();
if (item != null)
{
await SetAsync(cacheKey, item, expiration);
return new CacheValue<T>(item, true);
}
else
{
//TODO : Set a null value to cache!!

return CacheValue<T>.NoValue;
}
}

/// <summary>
/// Gets the specified cacheKey async.
/// </summary>
/// <returns>The async.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public async Task<CacheValue<T>> GetAsync<T>(string cacheKey) where T : class
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));

var value = await _localCachingProvider.GetAsync<T>(cacheKey);

if (value.HasValue)
{
return value;
}

value = await _distributedCachingProvider.GetAsync<T>(cacheKey);

if (value.HasValue)
{
return value;
}
else
{
//TODO : Set a null value to cache!!

return CacheValue<T>.NoValue;
}
}

/// <summary>
/// Remove the specified cacheKey.
/// </summary>
/// <returns>The remove.</returns>
/// <param name="cacheKey">Cache key.</param>
public void Remove(string cacheKey)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));

_localCachingProvider.Remove(cacheKey);
_distributedCachingProvider.Remove(cacheKey);
}

/// <summary>
/// Removes the specified cacheKey async.
/// </summary>
/// <returns>The async.</returns>
/// <param name="cacheKey">Cache key.</param>
public async Task RemoveAsync(string cacheKey)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));

await _localCachingProvider.RemoveAsync(cacheKey);
await _distributedCachingProvider.RemoveAsync(cacheKey);
}

/// <summary>
/// Set the specified cacheKey, cacheValue and expiration.
/// </summary>
/// <returns>The set.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="cacheValue">Cache value.</param>
/// <param name="expiration">Expiration.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public void Set<T>(string cacheKey, T cacheValue, TimeSpan expiration) where T : class
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

_localCachingProvider.Set(cacheKey,cacheValue,expiration);
_distributedCachingProvider.Set(cacheKey, cacheValue, expiration);
}

/// <summary>
/// Sets the specified cacheKey, cacheValue and expiration async.
/// </summary>
/// <returns>The async.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="cacheValue">Cache value.</param>
/// <param name="expiration">Expiration.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public async Task SetAsync<T>(string cacheKey, T cacheValue, TimeSpan expiration) where T : class
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

await _localCachingProvider.SetAsync(cacheKey, cacheValue, expiration);
await _distributedCachingProvider.SetAsync(cacheKey, cacheValue, expiration);
}
}
}

0 comments on commit 3aa72e2

Please sign in to comment.