├── redis-com-client ├── packages.config ├── ICacheManager.cs ├── CacheFactory.cs ├── Properties │ └── AssemblyInfo.cs ├── MyTable.cs ├── redis-com-client.csproj └── CacheManager.cs ├── README.md ├── redis-com-client-test ├── Properties │ └── AssemblyInfo.cs ├── redis-com-client-test.csproj └── BasicTest.cs ├── redis-com-client.sln ├── .gitattributes └── .gitignore /redis-com-client/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /redis-com-client/ICacheManager.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace redis_com_client 4 | { 5 | [ComVisible(true)] 6 | [Guid("c8109c73-2528-4e90-a999-81abd1fc7a70")] 7 | [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 8 | public interface ICacheManager 9 | { 10 | void Add(string key, object value); 11 | object Get(string key); 12 | void RemoveAll(); 13 | object this[string key] { get; set; } 14 | void Init(string cacheId); 15 | void Remove(string key); 16 | bool Exists(string key); 17 | void SetExpiration(string key, int milliseconds); 18 | } 19 | } -------------------------------------------------------------------------------- /redis-com-client/CacheFactory.cs: -------------------------------------------------------------------------------- 1 | using StackExchange.Redis; 2 | 3 | namespace redis_com_client 4 | { 5 | public class CacheFactory 6 | { 7 | private static ConnectionMultiplexer _redisClientsManager; 8 | 9 | 10 | private CacheFactory() 11 | { 12 | 13 | } 14 | 15 | public static IDatabase GetInstance() 16 | { 17 | if (_redisClientsManager == null) 18 | _redisClientsManager = ConnectionMultiplexer.Connect("localhost"); 19 | 20 | return _redisClientsManager.GetDatabase(); 21 | } 22 | 23 | public static IServer GetServer() 24 | { 25 | if (_redisClientsManager == null) 26 | _redisClientsManager = ConnectionMultiplexer.Connect("localhost"); 27 | 28 | return _redisClientsManager.GetServer("localhost", 6379); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # redis-com-client 2 | Redis Client for COM+ | StackExchange.Redis Wrapper 3 | 4 | This was made to be used on Classic ASP (ASP 3.0). 5 | 6 | Line command to install the COM+: 7 | 8 | %SystemRoot%\Microsoft.NET\Framework\v4.0.30319\regasm redis-com-client.dll /tlb:redis-com-client.tlb /codebase 9 | 10 | On the ASP side you have not create the object. I initialized this in the global.asa using this: 11 | - < OBJECT RUNAT=Server SCOPE=Application ID=Cache PROGID=CacheManager> 12 | 13 | However, it also works if you want to create a scoped object: 14 | - Set Cache = Server.CreateObject("CacheManager") 15 | 16 | 17 | Later you can use these operations: 18 | 19 | - Initiliaze (this operation is required in order to share the same Redis instance with N sites) 20 | Cache.Init "prefix1" 21 | 22 | -**Add** 23 | 24 | Cache.Add "key1", "value" 25 | 26 | **or** 27 | 28 | Cache("key1") = "value" 29 | 30 | -**Add with expiration** 31 | 32 | Cache.SetExpiration "key1", "value", 1000 'ms 33 | 34 | -**Get** 35 | 36 | Cache.Get "key1" 37 | 38 | **or** 39 | 40 | Cache("key1") 41 | 42 | -**Remove** 43 | 44 | Cache.Remove "key1" 45 | 46 | -**Remove All** 47 | 48 | Cache.RemoveAll() 49 | -------------------------------------------------------------------------------- /redis-com-client/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("redis-com-client")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("redis-com-client")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("6a8a31f6-4309-453d-84cf-202ea5eb7c75")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /redis-com-client-test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("redis-com-client-test")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("redis-com-client-test")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("9d586484-2934-467d-83f3-5686e7474ac6")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /redis-com-client.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "redis-com-client", "redis-com-client\redis-com-client.csproj", "{6A8A31F6-4309-453D-84CF-202EA5EB7C75}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "redis-com-client-test", "redis-com-client-test\redis-com-client-test.csproj", "{9D586484-2934-467D-83F3-5686E7474AC6}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {6A8A31F6-4309-453D-84CF-202EA5EB7C75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {6A8A31F6-4309-453D-84CF-202EA5EB7C75}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {6A8A31F6-4309-453D-84CF-202EA5EB7C75}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {6A8A31F6-4309-453D-84CF-202EA5EB7C75}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {9D586484-2934-467D-83F3-5686E7474AC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {9D586484-2934-467D-83F3-5686E7474AC6}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {9D586484-2934-467D-83F3-5686E7474AC6}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {9D586484-2934-467D-83F3-5686E7474AC6}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /redis-com-client/MyTable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace redis_com_client 5 | { 6 | public class MyTable 7 | { 8 | public List> ArrayCollumns {get; set;} //This typo is to make it different 9 | public List ArrayCollumn { get; set; } //This typo is to make it different 10 | 11 | public MyTable() 12 | { 13 | ArrayCollumns = new List>(); 14 | ArrayCollumn = new List(); 15 | } 16 | 17 | public MyTable(object[,] array) : this() 18 | { 19 | for (var column = 0; column < array.GetLength(0); column++) 20 | { 21 | ArrayCollumns.Add(new List()); 22 | } 23 | 24 | for (var column = 0; column < array.GetLength(0); column++) 25 | { 26 | for (var row = 0; row < array.GetLength(1); row++) 27 | { 28 | var value = array[column, row] == DBNull.Value ? null : array[column, row]; 29 | ArrayCollumns[column].Add(value); 30 | } 31 | } 32 | } 33 | 34 | public MyTable(object[] array) : this() 35 | { 36 | for (var column = 0; column < array.GetLength(0); column++) 37 | { 38 | var value = array[column] == DBNull.Value ? null : array[column]; 39 | ArrayCollumn.Add(value); 40 | } 41 | } 42 | 43 | public object GetArray() 44 | { 45 | if (ArrayCollumns.Count > 0) 46 | { 47 | var newArrayTwoDim = new object[ArrayCollumns.Count, ArrayCollumns[0].Count]; 48 | for (var i = 0; i < ArrayCollumns.Count; i++) 49 | { 50 | for (var j = 0; j < ArrayCollumns[i].Count; j++) 51 | { 52 | object value; 53 | if (ArrayCollumns[i][j] is long) 54 | value = int.Parse(ArrayCollumns[i][j].ToString()); 55 | else 56 | value = ArrayCollumns[i][j]; 57 | 58 | newArrayTwoDim[i,j] = value; 59 | } 60 | } 61 | return newArrayTwoDim; 62 | } 63 | 64 | var newArrayOneDim = new object[ArrayCollumn.Count]; 65 | for (var j = 0; j < ArrayCollumn.Count; j++) 66 | { 67 | object value; 68 | if (ArrayCollumn[j] is long) 69 | value = int.Parse(ArrayCollumn[j].ToString()); 70 | else 71 | value = ArrayCollumn[j]; 72 | 73 | newArrayOneDim[j] = value; 74 | } 75 | return newArrayOneDim; 76 | } 77 | 78 | } 79 | } -------------------------------------------------------------------------------- /redis-com-client/redis-com-client.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {6A8A31F6-4309-453D-84CF-202EA5EB7C75} 8 | Library 9 | Properties 10 | redis_com_client 11 | redis-com-client 12 | v4.6 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll 35 | True 36 | 37 | 38 | ..\packages\StackExchange.Redis.StrongName.1.1.603\lib\net46\StackExchange.Redis.StrongName.dll 39 | True 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | # DNX 42 | project.lock.json 43 | artifacts/ 44 | 45 | *_i.c 46 | *_p.c 47 | *_i.h 48 | *.ilk 49 | *.meta 50 | *.obj 51 | *.pch 52 | *.pdb 53 | *.pgc 54 | *.pgd 55 | *.rsp 56 | *.sbr 57 | *.tlb 58 | *.tli 59 | *.tlh 60 | *.tmp 61 | *.tmp_proj 62 | *.log 63 | *.vspscc 64 | *.vssscc 65 | .builds 66 | *.pidb 67 | *.svclog 68 | *.scc 69 | 70 | # Chutzpah Test files 71 | _Chutzpah* 72 | 73 | # Visual C++ cache files 74 | ipch/ 75 | *.aps 76 | *.ncb 77 | *.opensdf 78 | *.sdf 79 | *.cachefile 80 | 81 | # Visual Studio profiler 82 | *.psess 83 | *.vsp 84 | *.vspx 85 | 86 | # TFS 2012 Local Workspace 87 | $tf/ 88 | 89 | # Guidance Automation Toolkit 90 | *.gpState 91 | 92 | # ReSharper is a .NET coding add-in 93 | _ReSharper*/ 94 | *.[Rr]e[Ss]harper 95 | *.DotSettings.user 96 | 97 | # JustCode is a .NET coding add-in 98 | .JustCode 99 | 100 | # TeamCity is a build add-in 101 | _TeamCity* 102 | 103 | # DotCover is a Code Coverage Tool 104 | *.dotCover 105 | 106 | # NCrunch 107 | _NCrunch_* 108 | .*crunch*.local.xml 109 | 110 | # MightyMoose 111 | *.mm.* 112 | AutoTest.Net/ 113 | 114 | # Web workbench (sass) 115 | .sass-cache/ 116 | 117 | # Installshield output folder 118 | [Ee]xpress/ 119 | 120 | # DocProject is a documentation generator add-in 121 | DocProject/buildhelp/ 122 | DocProject/Help/*.HxT 123 | DocProject/Help/*.HxC 124 | DocProject/Help/*.hhc 125 | DocProject/Help/*.hhk 126 | DocProject/Help/*.hhp 127 | DocProject/Help/Html2 128 | DocProject/Help/html 129 | 130 | # Click-Once directory 131 | publish/ 132 | 133 | # Publish Web Output 134 | *.[Pp]ublish.xml 135 | *.azurePubxml 136 | ## TODO: Comment the next line if you want to checkin your 137 | ## web deploy settings but do note that will include unencrypted 138 | ## passwords 139 | #*.pubxml 140 | 141 | *.publishproj 142 | 143 | # NuGet Packages 144 | *.nupkg 145 | # The packages folder can be ignored because of Package Restore 146 | **/packages/* 147 | # except build/, which is used as an MSBuild target. 148 | !**/packages/build/ 149 | # Uncomment if necessary however generally it will be regenerated when needed 150 | #!**/packages/repositories.config 151 | 152 | # Windows Azure Build Output 153 | csx/ 154 | *.build.csdef 155 | 156 | # Windows Store app package directory 157 | AppPackages/ 158 | 159 | # Visual Studio cache files 160 | # files ending in .cache can be ignored 161 | *.[Cc]ache 162 | # but keep track of directories ending in .cache 163 | !*.[Cc]ache/ 164 | 165 | # Others 166 | ClientBin/ 167 | [Ss]tyle[Cc]op.* 168 | ~$* 169 | *~ 170 | *.dbmdl 171 | *.dbproj.schemaview 172 | *.pfx 173 | *.publishsettings 174 | node_modules/ 175 | orleans.codegen.cs 176 | 177 | # RIA/Silverlight projects 178 | Generated_Code/ 179 | 180 | # Backup & report files from converting an old project file 181 | # to a newer Visual Studio version. Backup files are not needed, 182 | # because we have git ;-) 183 | _UpgradeReport_Files/ 184 | Backup*/ 185 | UpgradeLog*.XML 186 | UpgradeLog*.htm 187 | 188 | # SQL Server files 189 | *.mdf 190 | *.ldf 191 | 192 | # Business Intelligence projects 193 | *.rdl.data 194 | *.bim.layout 195 | *.bim_*.settings 196 | 197 | # Microsoft Fakes 198 | FakesAssemblies/ 199 | 200 | # Node.js Tools for Visual Studio 201 | .ntvs_analysis.dat 202 | 203 | # Visual Studio 6 build log 204 | *.plg 205 | 206 | # Visual Studio 6 workspace options file 207 | *.opt 208 | 209 | # LightSwitch generated files 210 | GeneratedArtifacts/ 211 | _Pvt_Extensions/ 212 | ModelManifest.xml 213 | -------------------------------------------------------------------------------- /redis-com-client/CacheManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.EnterpriseServices; 3 | using System.Runtime.InteropServices; 4 | using Newtonsoft.Json; 5 | using StackExchange.Redis; 6 | 7 | namespace redis_com_client 8 | { 9 | [ComVisible(true)] 10 | [Guid("6e8c90dd-15b6-4ee9-83c1-f294d6dca2a8")] 11 | [ClassInterface(ClassInterfaceType.None)] 12 | [ProgId("CacheManager")] 13 | [Synchronization(SynchronizationOption.Disabled)] 14 | public class CacheManager : ICacheManager 15 | { 16 | private string _storePrefix; 17 | 18 | public CacheManager() 19 | { 20 | } 21 | 22 | public void SetExpiration(string key, int milliseconds) 23 | { 24 | CacheFactory.GetInstance().KeyExpire(GenerateFullKey(key), TimeSpan.FromMilliseconds(milliseconds)); 25 | } 26 | 27 | public void RemoveAll() 28 | { 29 | var mask = $"{_storePrefix}*"; 30 | CacheFactory.GetInstance().ScriptEvaluate("local keys = redis.call('keys', ARGV[1]) for i=1,#keys,5000 do redis.call('del', unpack(keys, i, math.min(i+4999, #keys))) end return keys", null, new RedisValue[] { mask }); 31 | } 32 | 33 | public object Get(string key) 34 | { 35 | var fullKey = GenerateFullKey(key); 36 | string pair = CacheFactory.GetInstance().StringGet(fullKey); 37 | 38 | if (string.IsNullOrEmpty(pair)) 39 | return null; 40 | 41 | if (!pair.Contains("ArrayCollumn")) 42 | return pair; 43 | 44 | var table = JsonConvert.DeserializeObject(pair); 45 | try { 46 | return (object[,])table.GetArray(); 47 | } 48 | catch (Exception) { 49 | return (object[])table.GetArray(); 50 | } 51 | } 52 | 53 | 54 | public void Add(string key, object value) 55 | { 56 | Add(key, value, 0); 57 | } 58 | 59 | private void Add(string key, object value, int millisecondsToExpire) 60 | { 61 | object valueToAdd = value?.ToString() ?? string.Empty; 62 | var fullKey = GenerateFullKey(key); 63 | 64 | if (value != null && value.GetType().IsArray) 65 | { 66 | try 67 | { 68 | var array = (object[,])value; 69 | 70 | var table = new MyTable(array); 71 | valueToAdd = JsonConvert.SerializeObject(table); 72 | } 73 | catch (Exception ex) 74 | { 75 | if (ex.Message.IndexOf("cast object", StringComparison.InvariantCultureIgnoreCase) > 0) //most likely the array is not bi-dimensional, try again with only 1 dimenion 76 | { 77 | var array = (object[])value; 78 | 79 | var table = new MyTable(array); 80 | valueToAdd = JsonConvert.SerializeObject(table); 81 | } 82 | else 83 | { 84 | throw; 85 | } 86 | } 87 | } 88 | 89 | if (millisecondsToExpire > 0) 90 | { 91 | CacheFactory.GetInstance().StringSet(fullKey, (string)valueToAdd, TimeSpan.FromMilliseconds(millisecondsToExpire)); 92 | } 93 | else 94 | { 95 | CacheFactory.GetInstance().StringSet(fullKey, (string)valueToAdd); 96 | } 97 | } 98 | 99 | public object this[string key] 100 | { 101 | get { return Get(key); } 102 | set { Add(key, value); } 103 | } 104 | 105 | public void Init(string cacheId) 106 | { 107 | _storePrefix = string.Concat(cacheId, ":"); 108 | } 109 | 110 | private string GenerateFullKey(string key) 111 | { 112 | if (string.IsNullOrEmpty(_storePrefix)) 113 | throw new Exception("no cache key defined - operation not allowed."); 114 | 115 | return (string.Concat(_storePrefix, key)); 116 | } 117 | 118 | public void Remove(string key) 119 | { 120 | CacheFactory.GetInstance().KeyDelete(GenerateFullKey(key)); 121 | } 122 | 123 | public bool Exists(string key) 124 | { 125 | return CacheFactory.GetInstance().KeyExists(GenerateFullKey(key)); 126 | } 127 | } 128 | } -------------------------------------------------------------------------------- /redis-com-client-test/redis-com-client-test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {9D586484-2934-467D-83F3-5686E7474AC6} 7 | Library 8 | Properties 9 | redis_com_client_test 10 | redis-com-client-test 11 | v4.6 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | False 18 | UnitTest 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {6A8A31F6-4309-453D-84CF-202EA5EB7C75} 59 | redis-com-client 60 | 61 | 62 | 63 | 64 | 65 | 66 | False 67 | 68 | 69 | False 70 | 71 | 72 | False 73 | 74 | 75 | False 76 | 77 | 78 | 79 | 80 | 81 | 82 | 89 | -------------------------------------------------------------------------------- /redis-com-client-test/BasicTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Text; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | using redis_com_client; 8 | 9 | namespace redis_com_client_test 10 | { 11 | [TestClass] 12 | public class BasicTest 13 | { 14 | 15 | private CacheManager _manager; 16 | 17 | [TestInitialize] 18 | public void Initialize() 19 | { 20 | _manager = new CacheManager(); 21 | _manager.Init("test1"); 22 | } 23 | 24 | 25 | [TestMethod] 26 | public void Add() 27 | { 28 | _manager.Add("key1", "abcde"); 29 | 30 | Assert.AreEqual("abcde", _manager.Get("key1")); 31 | } 32 | 33 | //[TestMethod] 34 | //public void SetExpiration() 35 | //{ 36 | // var wait = 5000; 37 | // var expiredValue = DateTime.Now; 38 | // _manager.SetExpiration("expired", expiredValue, wait); 39 | // 40 | // Assert.AreEqual(expiredValue.ToString(), _manager.Get("expired")); 41 | // Thread.Sleep(wait + 100); 42 | // Assert.IsNull(_manager.Get("expired")); 43 | //} 44 | 45 | [TestMethod] 46 | public void GetByObject() 47 | { 48 | _manager.Add("dk", "123"); 49 | Assert.AreEqual("123", _manager["dk"]); 50 | } 51 | 52 | [TestMethod] 53 | public void SetByObject() 54 | { 55 | _manager["dk"] = "123"; 56 | Assert.AreEqual("123", _manager["dk"]); 57 | } 58 | 59 | [TestMethod] 60 | public void Array() 61 | { 62 | var array = new object[,] {{1, 2, 3}, { "a", "b", "c" }, { "aa", "bb", "cc" } }; 63 | 64 | _manager["arraytest"] = array; 65 | 66 | var x = (object[,])_manager["arraytest"]; 67 | Assert.AreEqual(int.Parse("1"), x[0, 0]); //It guarantees int32 to VBScropt compability. 68 | } 69 | 70 | [TestMethod] 71 | public void ArraySpecialChar() 72 | { 73 | var specialChar = "#$%ˆ@"; 74 | var array = new object[,] { { 1, 2, 3 }, { specialChar, "b", "c" } }; 75 | 76 | _manager["arraytest"] = array; 77 | 78 | var x = (object[,])_manager["arraytest"]; 79 | Assert.AreEqual(specialChar, x[1, 0]); 80 | } 81 | 82 | [TestMethod] 83 | public void ArrayHtml() 84 | { 85 | var html = ""; 86 | var array = new object[,] { { 1, 2, 3 }, { html, "b", "c" } }; 87 | 88 | _manager["arraytest"] = array; 89 | 90 | var x = (object[,])_manager["arraytest"]; 91 | Assert.AreEqual(html, x[1, 0]); 92 | } 93 | 94 | [TestMethod] 95 | public void RemoveAllFromThisKey() 96 | { 97 | var manager2 = new CacheManager(); 98 | manager2.Init("test2"); 99 | manager2.Add("firstname", "22222"); 100 | manager2.Add("lastname", "33333"); 101 | 102 | _manager.Add("firstname", "firstname123"); 103 | _manager.Add("lastname", "lastname123"); 104 | _manager.RemoveAll(); 105 | 106 | Assert.IsNull(_manager["firstname"]); 107 | Assert.IsNull(_manager["lastname"]); 108 | Assert.IsNotNull(manager2["firstname"]); 109 | Assert.IsNotNull(manager2["lastname"]); 110 | } 111 | 112 | [TestMethod] 113 | public void Exists() 114 | { 115 | _manager.Add("exists", "12344"); 116 | Assert.IsTrue(_manager.Exists("exists")); 117 | } 118 | 119 | [TestMethod] 120 | public void NotExists() 121 | { 122 | Assert.IsFalse(_manager.Exists("notexists")); 123 | } 124 | 125 | [TestMethod] 126 | public void Remove() 127 | { 128 | _manager.Add("onekey", "12344"); 129 | _manager.Remove("onekey"); 130 | Assert.IsFalse(_manager.Exists("onekey")); 131 | } 132 | 133 | [TestMethod] 134 | public void SetExpirationExistingKey() 135 | { 136 | _manager.Add("key4", "12344"); 137 | Assert.IsTrue(_manager.Exists("key4")); 138 | _manager.SetExpiration("key4",1000); 139 | Thread.Sleep(2000); 140 | Assert.IsNull(_manager["key4"]); 141 | } 142 | 143 | [TestMethod] 144 | public void AddNullValue() 145 | { 146 | _manager.Add("null", null); 147 | Assert.IsTrue(_manager.Exists("null")); 148 | } 149 | 150 | [TestMethod] 151 | public void ReplaceDbNull() 152 | { 153 | var array = new object[,] {{10, 20}, {"asdf", DBNull.Value}}; 154 | _manager["DBNull"] = array; 155 | 156 | var result = (object[,])_manager["DBNull"]; 157 | Assert.IsNotNull(result); 158 | Assert.IsNull(result[1,1]); 159 | } 160 | 161 | [TestMethod] 162 | public void AddSameKeyTwice() 163 | { 164 | _manager["twice"] = 1; 165 | Thread.Sleep(500); 166 | _manager["twice"] = "asdf"; 167 | Assert.AreEqual("asdf", _manager["twice"]); 168 | } 169 | 170 | [TestMethod] 171 | public void Concurrent() 172 | { 173 | ArrayHtml(); 174 | var sb = new StringBuilder(); 175 | Parallel.For((long) 0, 1000, i => 176 | { 177 | sb.AppendFormat("i: {0}{1}", i, Environment.NewLine); 178 | var sw = new Stopwatch(); 179 | sw.Start(); 180 | object x = _manager["arraytest"]; 181 | sw.Stop(); 182 | sb.AppendFormat("i: {0} - time: {1}ms", i, sw.ElapsedMilliseconds); 183 | }); 184 | Console.WriteLine(sb); 185 | } 186 | 187 | [TestMethod] 188 | public void MyTableTwoDim() 189 | { 190 | var array = new object[,] { { 1, 2, 3 }, { "a", "b", "c" } }; 191 | var table = new MyTable(array); 192 | 193 | var newArray = (object[,])table.GetArray(); 194 | Assert.AreEqual(array[0, 0], newArray[0, 0]); 195 | Assert.AreEqual(array[1, 1], newArray[1, 1]); 196 | } 197 | 198 | [TestMethod] 199 | public void MyTableOneDim() 200 | { 201 | var array = new object[] { 1, 2, 3 } ; 202 | var table = new MyTable(array); 203 | 204 | var newArray = (object[])table.GetArray(); 205 | Assert.AreEqual(array[0], newArray[0]); 206 | Assert.AreEqual(array[1], newArray[1]); 207 | Assert.AreEqual(array[2], newArray[2]); 208 | } 209 | } 210 | } 211 | --------------------------------------------------------------------------------