LVD.ServiceStack.RoutedCacheClient
1.1.0
dotnet add package LVD.ServiceStack.RoutedCacheClient --version 1.1.0
NuGet\Install-Package LVD.ServiceStack.RoutedCacheClient -Version 1.1.0
<PackageReference Include="LVD.ServiceStack.RoutedCacheClient" Version="1.1.0" />
<PackageVersion Include="LVD.ServiceStack.RoutedCacheClient" Version="1.1.0" />
<PackageReference Include="LVD.ServiceStack.RoutedCacheClient" />
paket add LVD.ServiceStack.RoutedCacheClient --version 1.1.0
#r "nuget: LVD.ServiceStack.RoutedCacheClient, 1.1.0"
#:package LVD.ServiceStack.RoutedCacheClient@1.1.0
#addin nuget:?package=LVD.ServiceStack.RoutedCacheClient&version=1.1.0
#tool nuget:?package=LVD.ServiceStack.RoutedCacheClient&version=1.1.0
ServiceStack Routed Cache Client
What
The ServiceStack Routed Cache Client is an ICacheClient implementation
(ICacheClientExtended to be more exact) that acts as a facade
to a collection of multiple other cache clients.
It has minimum overhead and does not store cache values itself, but only routes
various cache operations (read, write, flush, remove etc.) to a specific registered client,
based on an associated rule (for instance, whether the key starts with a given string).
Why
The main issue for me was (and possibly many others) that I could not register
a different cache client for session storage (say, OrmLiteCacheClient),
whilst continuing to make use of the standard MemoryCacheClient .
How to use
1. Add namespace reference
using LVD.ServiceStackRoutedCacheClient.
2. Create your routed cache client instance
In this example, the default MemoryCacheClient provided by ServiceStack is used as a fallback client,
which means it will used to handle keys that are not matched by any of the registered rules.
IRoutedCacheClient routedCacheClient = new DefaultRoutedCacheClient(new MemoryCacheClient());
3. Register your other cache clients
For example, registering a ServiceStack OrmLite cache client for ServiceStack sessions:
OrmLiteCacheClient<CacheEntry> ormLiteCacheClient =
new OrmLiteCacheClient<CacheEntry>();
routedCacheClient.PushClientWithRule(new KeyStartsWithStringCacheClientRule(ormLiteCacheClient,
StringComparison.InvariantCultureIgnoreCase,
"urn:iauthsession:",
"sess:"));
Or simpler, using PushServiceStackSessionCacheClient(), which automatically registers your provided cache client
with a KeyStartsWithStringCacheClientRule and the above prefixes: urn:iauthsession: and sess:.
OrmLiteCacheClient<CacheEntry> ormLiteCacheClient =
new OrmLiteCacheClient<CacheEntry>();
routedCacheClient.PushServiceStackSessionCacheClient(ormLiteCacheClient);
4. Built-in routing behaviour
4.1. Built-in conditions
KeyStartsWithStringCacheClientRuleCondition- matches keys that start with a given sub-string;KeyEndsWithStringCacheClientRuleCondition- matches keys that end with a given sub-string;KeyMatchesRegexpCacheClientRuleCondition- matches keys based on a regular expression;ServiceStackSessionKeyCacheClientRuleCondition- matches keys used to store ServiceStack session data;AlwaysTrueCacheClientRuleCondition- matches any key;AlwaysFalseCacheClientRuleCondition- doesn't match anything;MatchAnyRuleCondition- allows composing conditions usingORboolean operator (i.e. returns true if at least one condition evaluates to true);MatchAllRuleCondition- allows composing conditions usingANDboolean operator (i.e. returns true if all conditions evaluate to true).
4.2. Built-in rules
GenericConditionBasedCacheClientRule- matches keys that satisfy a given condition;KeyStartsWithStringCacheClientRule- matches keys that start with a given sub-string (usesKeyStartsWithStringCacheClientRuleCondition);KeyEndsWithStringCacheClientRule- matches keys that end with a given sub-string (usesKeyEndsWithStringCacheClientRuleCondition);KeyMatchesRegexpCacheClientRule- matches keys based on a regular expression (usesKeyMatchesRegexpCacheClientRuleCondition);ServiceStackSessionKeyCacheClientRule- matches keys used to store ServiceStack session data (usesServiceStackSessionKeyCacheClientRuleCondition);AlwaysTrueCacheClientRule- matches any key (usesAlwaysTrueCacheClientRuleCondition);AlwaysFalseCacheClientRule- doesn't match anything (usesAlwaysFalseCacheClientRuleCondition).
5. Extending the routing behaviour
5.1. Creating custom conditions
Creating your own conditions is as easy as implementing IRoutedCacheClientRuleCondition
with the single method bool Matches ( string key ).
This is also the recommended way of exteding the library's routing behaviour.
As an example, here is the implementation of the built-in KeyStartsWithStringCacheClientRuleCondition condition:
public class KeyStartsWithStringCacheClientRuleCondition : IRoutedCacheClientRuleCondition
{
private List<string> mTokens = new List<string>();
private StringComparison mStringComparisonMode;
public KeyStartsWithStringCacheClientRuleCondition ( StringComparison stringComparisonMode,
params string[] tokens )
{
if ( tokens == null || tokens.Length == 0 )
throw new ArgumentNullException( nameof( tokens ) );
mTokens.AddRange( tokens );
mStringComparisonMode = stringComparisonMode;
}
public bool Matches ( string key )
{
if ( string.IsNullOrWhiteSpace( key ) )
throw new ArgumentNullException( nameof( key ) );
foreach ( string token in mTokens )
if ( key.StartsWith( token, mStringComparisonMode ) )
return true;
return false;
}
public StringComparison StringComparisonMode
=> mStringComparisonMode;
}
5.2. Creating custom rules
Creating your own rules is as easy as
- extending the GenericConditionBasedCacheClientRule class and providing a condition to this base class (this is a useful shortcut to always instantiating GenericConditionBasedCacheClientRule with the same condition).
- or extending the BaseCacheClientRule class and providing an implementation for the bool Matches ( string key ) method (should you wish to bypass using a condition altogether).
Example #1 - the implementation of the built-in KeyStartsWithStringCacheClientRule rule:
public class KeyStartsWithStringCacheClientRule : GenericConditionBasedCacheClientRule
{
public KeyStartsWithStringCacheClientRule ( ICacheClient cacheClient,
KeyStartsWithStringCacheClientRuleCondition condition )
: base( cacheClient, condition )
{
return;
}
public KeyStartsWithStringCacheClientRule ( ICacheClient cacheClient,
StringComparison stringComparisonMode,
params string[] tokens )
: this( cacheClient, new KeyStartsWithStringCacheClientRuleCondition( stringComparisonMode, tokens ) )
{
return;
}
}
Example #2 - the implementation of the built-in GenericConditionBasedCacheClientRule rule:
public class GenericConditionBasedCacheClientRule : BaseCacheClientRule
{
private IRoutedCacheClientRuleCondition mCondition;
public GenericConditionBasedCacheClientRule ( ICacheClient cacheClient, IRoutedCacheClientRuleCondition condition )
: base( cacheClient )
{
mCondition = condition
?? throw new ArgumentNullException( nameof( condition ) );
}
public override bool Matches ( string key )
{
if ( string.IsNullOrWhiteSpace( key ) )
throw new ArgumentNullException( nameof( key ) );
return mCondition.Matches( key );
}
private IRoutedCacheClientRuleCondition Condition
=> mCondition;
}
6. Dispose behaviour
The dispose behaviour of the DefaultRoutedCacheClient, after version 1.1.0 is as follows:
- to automatically dispose all the registered cache clients by default (this can now be configured);
- to throw throw
ObjectDisposedExceptionwhen invoking methods on diposed instances.
To change how DefaultRoutedCacheClient handles various registered cache clients you may:
- use
DefaultRoutedCacheClient ( ICacheClient fallbackClient, bool autoDispose )constructor to set whether or not the fallback cache client should be disposed along with theDefaultRoutedCacheClientit is registered with; - use
IRoutedCacheClientRule.AutoDisposeproperty to set whether the cache client associated with a rule should be disposed along with theDefaultRoutedCacheClientit is registered with.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 is compatible. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.7.2
- ServiceStack.Interfaces (>= 5.4.0)
-
.NETStandard 2.0
- ServiceStack.Interfaces (>= 5.4.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.