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" />
paket add LVD.ServiceStack.RoutedCacheClient --version 1.1.0
#r "nuget: LVD.ServiceStack.RoutedCacheClient, 1.1.0"
// Install LVD.ServiceStack.RoutedCacheClient as a Cake Addin #addin nuget:?package=LVD.ServiceStack.RoutedCacheClient&version=1.1.0 // Install LVD.ServiceStack.RoutedCacheClient as a Cake Tool #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 usingOR
boolean operator (i.e. returns true if at least one condition evaluates to true);MatchAllRuleCondition
- allows composing conditions usingAND
boolean 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
ObjectDisposedException
when 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 theDefaultRoutedCacheClient
it is registered with; - use
IRoutedCacheClientRule.AutoDispose
property to set whether the cache client associated with a rule should be disposed along with theDefaultRoutedCacheClient
it 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. |
.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.