From 38a9f394b4d92b3f80e3a31b48c91dde30687cd4 Mon Sep 17 00:00:00 2001 From: catcherwong Date: Mon, 13 Nov 2017 21:03:53 +0800 Subject: [PATCH 01/11] :sparkles: Add CacheEntry and IEasyCachingProvider --- EasyCaching/src/EasyCaching.Core/Class1.cs | 8 +++ src/EasyCaching.Core/CacheEntry.cs | 53 ++++++++++++++++++++ src/EasyCaching.Core/IEasyCachingProvider.cs | 22 ++++++++ 3 files changed, 83 insertions(+) create mode 100644 EasyCaching/src/EasyCaching.Core/Class1.cs create mode 100644 src/EasyCaching.Core/CacheEntry.cs create mode 100644 src/EasyCaching.Core/IEasyCachingProvider.cs diff --git a/EasyCaching/src/EasyCaching.Core/Class1.cs b/EasyCaching/src/EasyCaching.Core/Class1.cs new file mode 100644 index 00000000..2133ab85 --- /dev/null +++ b/EasyCaching/src/EasyCaching.Core/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace EasyCaching.Core +{ + public class Class1 + { + } +} diff --git a/src/EasyCaching.Core/CacheEntry.cs b/src/EasyCaching.Core/CacheEntry.cs new file mode 100644 index 00000000..0c41deeb --- /dev/null +++ b/src/EasyCaching.Core/CacheEntry.cs @@ -0,0 +1,53 @@ +namespace EasyCaching.Core +{ + using System; + + /// + /// Cache entry. + /// + public class CacheEntry + { + /// + /// Initializes a new instance of the class. + /// + /// Cache key. + /// Cache value. + /// Absolute expiration relative to now. + public CacheEntry(string cacheKey, object cacheValue, TimeSpan absoluteExpirationRelativeToNow) + { + if (string.IsNullOrWhiteSpace(cacheKey)) + throw new ArgumentNullException(nameof(cacheKey)); + + if (cacheValue == null) + throw new ArgumentNullException(nameof(cacheValue)); + + if (absoluteExpirationRelativeToNow <= TimeSpan.Zero) + throw new ArgumentOutOfRangeException( + nameof(absoluteExpirationRelativeToNow), + absoluteExpirationRelativeToNow, + "The relative expiration value must be positive."); + + this.CacheKey = cacheKey; + this.CacheValue = cacheValue; + this.AbsoluteExpirationRelativeToNow = absoluteExpirationRelativeToNow; + } + + /// + /// Gets the cache key. + /// + /// The cache key. + public string CacheKey { get; private set; } + + /// + /// Gets the cache value. + /// + /// The cache value. + public object CacheValue { get; private set; } + + /// + /// Gets the absolute expiration relative to now. + /// + /// The absolute expiration relative to now. + public TimeSpan AbsoluteExpirationRelativeToNow { get; private set; } + } +} diff --git a/src/EasyCaching.Core/IEasyCachingProvider.cs b/src/EasyCaching.Core/IEasyCachingProvider.cs new file mode 100644 index 00000000..acb00e2c --- /dev/null +++ b/src/EasyCaching.Core/IEasyCachingProvider.cs @@ -0,0 +1,22 @@ +namespace EasyCaching.Core +{ + /// + /// EasyCaching provider. + /// + public interface IEasyCachingProvider + { + /// + /// Set the specified cacheEntry. + /// + /// + /// Cache entry. + void Set(CacheEntry cacheEntry); + + /// + /// Get the specified cacheKey. + /// + /// The cache value. + /// Cache key. + object Get(string cacheKey); + } +} From fc6ab432b2aa00a9952779bd5d88a1d62cc3c653 Mon Sep 17 00:00:00 2001 From: Catcher Wong Date: Mon, 13 Nov 2017 21:52:03 +0800 Subject: [PATCH 02/11] :fire: Delete useless file --- EasyCaching/src/EasyCaching.Core/Class1.cs | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 EasyCaching/src/EasyCaching.Core/Class1.cs diff --git a/EasyCaching/src/EasyCaching.Core/Class1.cs b/EasyCaching/src/EasyCaching.Core/Class1.cs deleted file mode 100644 index 2133ab85..00000000 --- a/EasyCaching/src/EasyCaching.Core/Class1.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; - -namespace EasyCaching.Core -{ - public class Class1 - { - } -} From c05d5b1980f08c0c01fce938432d345b1683a1ca Mon Sep 17 00:00:00 2001 From: catcherwong Date: Tue, 14 Nov 2017 20:50:02 +0800 Subject: [PATCH 03/11] :sparkles: Add EasyCachingAttribute --- src/EasyCaching.Core/EasyCachingAttribute.cs | 20 ++++++++++++++++++ src/EasyCaching.Memory/.DS_Store | Bin 0 -> 6148 bytes src/EasyCaching.Memory/Class1.cs | 8 +++++++ .../EasyCaching.Memory.csproj | 7 ++++++ .../MemoryCachingProvider.cs | 10 +++++++++ 5 files changed, 45 insertions(+) create mode 100644 src/EasyCaching.Core/EasyCachingAttribute.cs create mode 100644 src/EasyCaching.Memory/.DS_Store create mode 100644 src/EasyCaching.Memory/Class1.cs create mode 100644 src/EasyCaching.Memory/EasyCaching.Memory.csproj create mode 100644 src/EasyCaching.Memory/MemoryCachingProvider.cs diff --git a/src/EasyCaching.Core/EasyCachingAttribute.cs b/src/EasyCaching.Core/EasyCachingAttribute.cs new file mode 100644 index 00000000..6f37cd73 --- /dev/null +++ b/src/EasyCaching.Core/EasyCachingAttribute.cs @@ -0,0 +1,20 @@ +namespace EasyCaching.Core +{ + using System; + + /// + /// Easycaching attribute. + /// + [AttributeUsage(AttributeTargets.Method)] + public class EasyCachingAttribute : Attribute + { + /// + /// Gets or sets the absolute expiration relative to now. + /// + /// + /// 30 sec. + /// + /// The absolute expiration relative to now. + public long AbsoluteExpirationRelativeToNow { get; set; } = 30; + } +} diff --git a/src/EasyCaching.Memory/.DS_Store b/src/EasyCaching.Memory/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 + + + netstandard2.0 + + + diff --git a/src/EasyCaching.Memory/MemoryCachingProvider.cs b/src/EasyCaching.Memory/MemoryCachingProvider.cs new file mode 100644 index 00000000..63cfe418 --- /dev/null +++ b/src/EasyCaching.Memory/MemoryCachingProvider.cs @@ -0,0 +1,10 @@ +using System; +namespace EasyCaching.Memory +{ + public class MemoryCachingProvider + { + public MemoryCachingProvider() + { + } + } +} From c937da0fc0ec9b7783172e9c1abdd88fe870cf07 Mon Sep 17 00:00:00 2001 From: catcherwong Date: Tue, 14 Nov 2017 20:50:34 +0800 Subject: [PATCH 04/11] :sparkles: Add MemoryCaching Project --- .../EasyCaching.Memory.csproj | 6 +++ .../MemoryCachingProvider.cs | 47 +++++++++++++++++-- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/EasyCaching.Memory/EasyCaching.Memory.csproj b/src/EasyCaching.Memory/EasyCaching.Memory.csproj index 72764a66..dd07f2d3 100644 --- a/src/EasyCaching.Memory/EasyCaching.Memory.csproj +++ b/src/EasyCaching.Memory/EasyCaching.Memory.csproj @@ -4,4 +4,10 @@ netstandard2.0 + + + + + + diff --git a/src/EasyCaching.Memory/MemoryCachingProvider.cs b/src/EasyCaching.Memory/MemoryCachingProvider.cs index 63cfe418..cbc9fd56 100644 --- a/src/EasyCaching.Memory/MemoryCachingProvider.cs +++ b/src/EasyCaching.Memory/MemoryCachingProvider.cs @@ -1,10 +1,49 @@ -using System; -namespace EasyCaching.Memory +namespace EasyCaching.Memory { - public class MemoryCachingProvider + using System; + using EasyCaching.Core; + using Microsoft.Extensions.Caching.Memory; + + /// + /// MemoryCaching provider. + /// + public class MemoryCachingProvider : IEasyCachingProvider { - public MemoryCachingProvider() + /// + /// The MemoryCache. + /// + private readonly IMemoryCache _cache; + + /// + /// Initializes a new instance of the class. + /// + /// Microsoft MemoryCache. + public MemoryCachingProvider(IMemoryCache cache) { + this._cache = cache; + } + + /// + /// Get cacheValue by specified cacheKey. + /// + /// The cacheValue. + /// Cache key. + public object Get(string cacheKey) + { + if (string.IsNullOrWhiteSpace(cacheKey)) + throw new ArgumentNullException(nameof(cacheKey)); + + return _cache.Get(cacheKey); + } + + /// + /// Set the specified cacheEntry. + /// + /// The set. + /// Cache entry. + public void Set(CacheEntry cacheEntry) + { + _cache.Set(cacheEntry.CacheKey, cacheEntry.CacheValue, cacheEntry.AbsoluteExpirationRelativeToNow); } } } From 80f201c02394e6629835acbe756be41eb752fc37 Mon Sep 17 00:00:00 2001 From: catcherwong Date: Tue, 14 Nov 2017 20:56:18 +0800 Subject: [PATCH 05/11] :wrench: Update gitignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 940794e6..c01b145b 100644 --- a/.gitignore +++ b/.gitignore @@ -286,3 +286,7 @@ __pycache__/ *.btm.cs *.odx.cs *.xsd.cs + +#MACOS + +.DS_Store From 70a9376b50f02633bc361bf323dbce1d763c5f7e Mon Sep 17 00:00:00 2001 From: Catcher Wong Date: Tue, 14 Nov 2017 20:59:19 +0800 Subject: [PATCH 06/11] :fire: Delete useless file --- src/EasyCaching.Memory/Class1.cs | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 src/EasyCaching.Memory/Class1.cs diff --git a/src/EasyCaching.Memory/Class1.cs b/src/EasyCaching.Memory/Class1.cs deleted file mode 100644 index 948fd508..00000000 --- a/src/EasyCaching.Memory/Class1.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; - -namespace EasyCaching.Memory -{ - public class Class1 - { - } -} From 0ee993ca7c0696e286b48b52887b36f44570e695 Mon Sep 17 00:00:00 2001 From: Catcher Wong Date: Tue, 14 Nov 2017 20:59:43 +0800 Subject: [PATCH 07/11] :fire: Delete useless file --- src/EasyCaching.Memory/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/EasyCaching.Memory/.DS_Store diff --git a/src/EasyCaching.Memory/.DS_Store b/src/EasyCaching.Memory/.DS_Store deleted file mode 100644 index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Tue, 14 Nov 2017 21:01:25 +0800 Subject: [PATCH 08/11] :sparkles: Add solution and project --- EasyCaching.sln | 33 ++++++++++++++++++++ src/EasyCaching.Core/EasyCaching.Core.csproj | 7 +++++ 2 files changed, 40 insertions(+) create mode 100644 EasyCaching.sln create mode 100644 src/EasyCaching.Core/EasyCaching.Core.csproj diff --git a/EasyCaching.sln b/EasyCaching.sln new file mode 100644 index 00000000..67147dbb --- /dev/null +++ b/EasyCaching.sln @@ -0,0 +1,33 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A0F5CC7E-155F-4726-8DEB-E966950B3FE9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{F88D727A-9F9C-43D9-90B1-D4A02BF8BC98}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{EBB55F65-7D07-4281-8D5E-7B0CA88E1AD0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyCaching.Core", "src\EasyCaching.Core\EasyCaching.Core.csproj", "{CE61FAA2-0233-451C-991D-4222ED61C84B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyCaching.Memory", "src\EasyCaching.Memory\EasyCaching.Memory.csproj", "{B9490432-737B-4518-B851-9D40FD29B392}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CE61FAA2-0233-451C-991D-4222ED61C84B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CE61FAA2-0233-451C-991D-4222ED61C84B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CE61FAA2-0233-451C-991D-4222ED61C84B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CE61FAA2-0233-451C-991D-4222ED61C84B}.Release|Any CPU.Build.0 = Release|Any CPU + {B9490432-737B-4518-B851-9D40FD29B392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B9490432-737B-4518-B851-9D40FD29B392}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B9490432-737B-4518-B851-9D40FD29B392}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B9490432-737B-4518-B851-9D40FD29B392}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {CE61FAA2-0233-451C-991D-4222ED61C84B} = {A0F5CC7E-155F-4726-8DEB-E966950B3FE9} + {B9490432-737B-4518-B851-9D40FD29B392} = {A0F5CC7E-155F-4726-8DEB-E966950B3FE9} + EndGlobalSection +EndGlobal diff --git a/src/EasyCaching.Core/EasyCaching.Core.csproj b/src/EasyCaching.Core/EasyCaching.Core.csproj new file mode 100644 index 00000000..72764a66 --- /dev/null +++ b/src/EasyCaching.Core/EasyCaching.Core.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + + From 282b68373e145a3fa0498ad2bf841b8c1f073fd0 Mon Sep 17 00:00:00 2001 From: catcherwong Date: Wed, 15 Nov 2017 21:21:19 +0800 Subject: [PATCH 09/11] :sparkles: Add EmptyCachingObject and EasyCachingManager --- src/EasyCaching.Core/EasyCachingManager.cs | 10 ++++++++++ src/EasyCaching.Core/EmptyCachingObject.cs | 10 ++++++++++ 2 files changed, 20 insertions(+) create mode 100644 src/EasyCaching.Core/EasyCachingManager.cs create mode 100644 src/EasyCaching.Core/EmptyCachingObject.cs diff --git a/src/EasyCaching.Core/EasyCachingManager.cs b/src/EasyCaching.Core/EasyCachingManager.cs new file mode 100644 index 00000000..9788c5fc --- /dev/null +++ b/src/EasyCaching.Core/EasyCachingManager.cs @@ -0,0 +1,10 @@ +using System; +namespace EasyCaching.Core +{ + public class EasyCachingManager + { + public EasyCachingManager() + { + } + } +} diff --git a/src/EasyCaching.Core/EmptyCachingObject.cs b/src/EasyCaching.Core/EmptyCachingObject.cs new file mode 100644 index 00000000..67144e54 --- /dev/null +++ b/src/EasyCaching.Core/EmptyCachingObject.cs @@ -0,0 +1,10 @@ +namespace EasyCaching.Core +{ + /// + /// Empty caching object. + /// + public class EmptyCachingObject + { + + } +} From 26cca02d05a25c1b052eb61ba9ff126e5e000159 Mon Sep 17 00:00:00 2001 From: catcherwong Date: Wed, 15 Nov 2017 21:23:12 +0800 Subject: [PATCH 10/11] :wrench: Update EasyCachingManage --- src/EasyCaching.Core/EasyCachingManager.cs | 113 ++++++++++++++++++++- 1 file changed, 109 insertions(+), 4 deletions(-) diff --git a/src/EasyCaching.Core/EasyCachingManager.cs b/src/EasyCaching.Core/EasyCachingManager.cs index 9788c5fc..1a1cecd5 100644 --- a/src/EasyCaching.Core/EasyCachingManager.cs +++ b/src/EasyCaching.Core/EasyCachingManager.cs @@ -1,10 +1,115 @@ -using System; -namespace EasyCaching.Core +namespace EasyCaching.Core { + using System; + using System.Collections.Generic; + + /// + /// Easycaching manager. + /// public class EasyCachingManager { - public EasyCachingManager() + /// + /// The caching providers. + /// + private readonly IEasyCachingProvider[] _cachingProviders; + + /// + /// Initializes a new instance of the class. + /// + /// Caching providers. + public EasyCachingManager(IEasyCachingProvider[] cachingProviders) { + if (cachingProviders == null || cachingProviders.Length <= 0) + { + throw new ArgumentNullException(nameof(cachingProviders)); + } + + this._cachingProviders = cachingProviders; } + + /// + /// Get cacheValue by specified cacheKey. + /// + /// The cacheValue. + /// Cache key. + public object Get(string cacheKey) + { + if (string.IsNullOrWhiteSpace(cacheKey)) + { + throw new ArgumentNullException(nameof(cacheKey)); + } + + object result = null; + + var missed = new HashSet(); + + for (int i = 0; i < _cachingProviders.Length; i++) + { + var cachingProvider = _cachingProviders[i]; + + var cacheValue = cachingProvider.Get(cacheKey); + + if (cacheValue != null) + { + result = cacheValue; + break; + } + else + { + missed.Add(i); + } + } + + if (result == null) + { + result = new EmptyCachingObject(); + } + + //handle missed cache + foreach (var item in missed) + { + var cachingProvider = _cachingProviders[item]; + + var cacheEntry = new CacheEntry(cacheKey, + result, + result.GetType().Equals(typeof(EmptyCachingObject)) + ? TimeSpan.FromSeconds(120) + : TimeSpan.FromSeconds(3600 + new Random().Next(1, 120))); + cachingProvider.Set(cacheEntry); + } + + return result; + } + + /// + /// Set the specified cacheKey, cacheValue and absoluteExpirationRelativeToNow. + /// + /// The set. + /// Cache key. + /// Cache value. + /// Absolute expiration relative to now. + public void Set(string cacheKey, object cacheValue, TimeSpan absoluteExpirationRelativeToNow) + { + var cacheEntry = new CacheEntry(cacheKey, cacheValue, absoluteExpirationRelativeToNow); + this.Set(cacheEntry); + } + + /// + /// Set the specified cacheEntry. + /// + /// The set. + /// Cache entry. + public void Set(CacheEntry cacheEntry) + { + for (int i = 0; i < _cachingProviders.Length; i++) + { + var cachingProvider = _cachingProviders[i]; + + cacheEntry.AbsoluteExpirationRelativeToNow.Add(TimeSpan.FromSeconds(new Random().Next(1, 120))); + + cachingProvider.Set(cacheEntry); + } + } + } -} +} \ No newline at end of file From 7fc1e869db81ecd0cbb3a16a1bed54653736c567 Mon Sep 17 00:00:00 2001 From: catcherwong Date: Mon, 27 Nov 2017 21:13:08 +0800 Subject: [PATCH 11/11] :sparkles: Add Caching Interceptor. --- EasyCaching.sln | 7 + src/EasyCaching.Core/EasyCaching.Core.csproj | 3 + src/EasyCaching.Core/EasyCachingAttribute.cs | 20 -- src/EasyCaching.Core/Internal/ICachable.cs | 14 ++ .../CachingInterceptor.cs | 173 ++++++++++++++++++ .../EasyCaching.Extensions.csproj | 14 ++ 6 files changed, 211 insertions(+), 20 deletions(-) delete mode 100644 src/EasyCaching.Core/EasyCachingAttribute.cs create mode 100644 src/EasyCaching.Core/Internal/ICachable.cs create mode 100644 src/EasyCaching.Extensions/CachingInterceptor.cs create mode 100644 src/EasyCaching.Extensions/EasyCaching.Extensions.csproj diff --git a/EasyCaching.sln b/EasyCaching.sln index 67147dbb..92be08e5 100644 --- a/EasyCaching.sln +++ b/EasyCaching.sln @@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyCaching.Core", "src\Eas EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyCaching.Memory", "src\EasyCaching.Memory\EasyCaching.Memory.csproj", "{B9490432-737B-4518-B851-9D40FD29B392}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyCaching.Extensions", "src\EasyCaching.Extensions\EasyCaching.Extensions.csproj", "{679ABDB5-7218-4B4E-A632-10612750CD74}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -25,9 +27,14 @@ Global {B9490432-737B-4518-B851-9D40FD29B392}.Debug|Any CPU.Build.0 = Debug|Any CPU {B9490432-737B-4518-B851-9D40FD29B392}.Release|Any CPU.ActiveCfg = Release|Any CPU {B9490432-737B-4518-B851-9D40FD29B392}.Release|Any CPU.Build.0 = Release|Any CPU + {679ABDB5-7218-4B4E-A632-10612750CD74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {679ABDB5-7218-4B4E-A632-10612750CD74}.Debug|Any CPU.Build.0 = Debug|Any CPU + {679ABDB5-7218-4B4E-A632-10612750CD74}.Release|Any CPU.ActiveCfg = Release|Any CPU + {679ABDB5-7218-4B4E-A632-10612750CD74}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {CE61FAA2-0233-451C-991D-4222ED61C84B} = {A0F5CC7E-155F-4726-8DEB-E966950B3FE9} {B9490432-737B-4518-B851-9D40FD29B392} = {A0F5CC7E-155F-4726-8DEB-E966950B3FE9} + {679ABDB5-7218-4B4E-A632-10612750CD74} = {A0F5CC7E-155F-4726-8DEB-E966950B3FE9} EndGlobalSection EndGlobal diff --git a/src/EasyCaching.Core/EasyCaching.Core.csproj b/src/EasyCaching.Core/EasyCaching.Core.csproj index 72764a66..810abdba 100644 --- a/src/EasyCaching.Core/EasyCaching.Core.csproj +++ b/src/EasyCaching.Core/EasyCaching.Core.csproj @@ -4,4 +4,7 @@ netstandard2.0 + + + diff --git a/src/EasyCaching.Core/EasyCachingAttribute.cs b/src/EasyCaching.Core/EasyCachingAttribute.cs deleted file mode 100644 index 6f37cd73..00000000 --- a/src/EasyCaching.Core/EasyCachingAttribute.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace EasyCaching.Core -{ - using System; - - /// - /// Easycaching attribute. - /// - [AttributeUsage(AttributeTargets.Method)] - public class EasyCachingAttribute : Attribute - { - /// - /// Gets or sets the absolute expiration relative to now. - /// - /// - /// 30 sec. - /// - /// The absolute expiration relative to now. - public long AbsoluteExpirationRelativeToNow { get; set; } = 30; - } -} diff --git a/src/EasyCaching.Core/Internal/ICachable.cs b/src/EasyCaching.Core/Internal/ICachable.cs new file mode 100644 index 00000000..fb71c53e --- /dev/null +++ b/src/EasyCaching.Core/Internal/ICachable.cs @@ -0,0 +1,14 @@ +namespace EasyCaching.Core.Internal +{ + /// + /// Cachable. + /// + public interface ICachable + { + /// + /// Gets the cache key. + /// + /// The cache key. + string CacheKey { get; } + } +} diff --git a/src/EasyCaching.Extensions/CachingInterceptor.cs b/src/EasyCaching.Extensions/CachingInterceptor.cs new file mode 100644 index 00000000..b59fdcfc --- /dev/null +++ b/src/EasyCaching.Extensions/CachingInterceptor.cs @@ -0,0 +1,173 @@ +namespace EasyCaching.Extensions +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + using System.Text; + using System.Threading.Tasks; + using AspectCore.DynamicProxy; + using AspectCore.Injector; + using EasyCaching.Core.Internal; + using EasyCaching.Core; + + /// + /// Caching interceptor. + /// + public class CachingInterceptor : AbstractInterceptorAttribute + { + + /// + /// Gets or sets the absolute expiration. + /// + /// The absolute expiration. + public int AbsoluteExpiration { get; set; } = 30; + + + /// + /// Gets or sets the parameter count to generate cache key. + /// + /// The parameter count. + public int ParamCount { get; set; } = 5; + + + /// + /// Gets or sets the cache provider. + /// + /// The cache provider. + [FromContainer] + public IEasyCachingProvider CacheProvider { get; set; } + + /// + /// The link char of cache key. + /// + private char _linkChar = ':'; + + /// + /// Invoke the specified context and next. + /// + /// The invoke. + /// Context. + /// Next. + public async override Task Invoke(AspectContext context, AspectDelegate next) + { + var interceptorAttribute = GetInterceptorAttributeInfo(context.ServiceMethod); + if (interceptorAttribute != null) + { + await ProceedCaching(context, next, interceptorAttribute); + } + else + { + await next(context); + } + } + + /// + /// Gets the QC aching attribute info. + /// + /// The QC aching attribute info. + /// Method. + private CachingInterceptor GetInterceptorAttributeInfo(MethodInfo method) + { + return method.GetCustomAttributes(true).FirstOrDefault(x => x.GetType() == typeof(CachingInterceptor)) as CachingInterceptor; + } + + /// + /// Proceeds the caching. + /// + /// The caching. + /// Context. + /// Next. + /// Attribute. + private async Task ProceedCaching(AspectContext context, AspectDelegate next, CachingInterceptor attribute) + { + var cacheKey = GenerateCacheKey(context, attribute.ParamCount); + + var cacheValue = CacheProvider.Get(cacheKey); + if (cacheValue != null) + { + context.ReturnValue = cacheValue; + return; + } + + await next(context); + + if (!string.IsNullOrWhiteSpace(cacheKey)) + { + CacheEntry entry = new CacheEntry(cacheKey, context.ReturnValue, TimeSpan.FromSeconds(attribute.AbsoluteExpiration)); + CacheProvider.Set(entry); + } + } + + /// + /// Generates the cache key. + /// + /// The cache key. + /// Context. + /// Parameter count. + private string GenerateCacheKey(AspectContext context, int paramCount) + { + var typeName = context.ServiceMethod.DeclaringType.Name; + var methodName = context.ServiceMethod.Name; + var methodArguments = this.FormatArgumentsToPartOfCacheKey(context.ServiceMethod.GetParameters(), paramCount); + + return this.GenerateCacheKey(typeName, methodName, methodArguments); + } + + /// + /// Generates the cache key. + /// + /// The cache key. + /// Type name. + /// Method name. + /// Parameters. + private string GenerateCacheKey(string typeName, string methodName, IList parameters) + { + var builder = new StringBuilder(); + + builder.Append(typeName); + builder.Append(_linkChar); + + builder.Append(methodName); + builder.Append(_linkChar); + + foreach (var param in parameters) + { + builder.Append(param); + builder.Append(_linkChar); + } + + return builder.ToString().TrimEnd(_linkChar); + } + + /// + /// Formats the arguments to part of cache key. + /// + /// The arguments to part of cache key. + /// Method arguments. + /// Max parameter count. + private IList FormatArgumentsToPartOfCacheKey(IList methodArguments, int paramCount = 5) + { + return methodArguments.Select(this.GetArgumentValue).Take(paramCount).ToList(); + } + + /// + /// Gets the argument value. + /// + /// The argument value. + /// Argument. + private string GetArgumentValue(object arg) + { + if (arg is int || arg is long || arg is string) + return arg.ToString(); + + if (arg is DateTime) + return ((DateTime)arg).ToString("yyyyMMddHHmmss"); + + if (arg is ICachable) + return ((ICachable)arg).CacheKey; + + return null; + } + } +} diff --git a/src/EasyCaching.Extensions/EasyCaching.Extensions.csproj b/src/EasyCaching.Extensions/EasyCaching.Extensions.csproj new file mode 100644 index 00000000..74044a6a --- /dev/null +++ b/src/EasyCaching.Extensions/EasyCaching.Extensions.csproj @@ -0,0 +1,14 @@ + + + + netstandard2.0 + + + + + + + + + +