One big goal of CacheManager is to make it easy to work with different cache systems, but at the same time it should be flexible to adopt to different needs. Therefore, the configuration is a pretty important part of CacheManager.
You can choose from three different ways to configure CacheManager:
- By code, using the
CacheFactory
orConfigurationBuilder
- By using
Microsoft.Extensions.Configuration
- Via
web/app.config
using the CacheManager's configuration section
CacheFactorylink
To create a Cache Manager instance, you can use the CacheFactory
class which has two different methods:
Build
can be used to create a new cache configuration using a fluent configuration builder.
var cache = CacheFactory.Build(settings => settings
.WithUpdateMode(CacheUpdateMode.Up)
.WithSystemRuntimeCacheHandle()
.WithExpiration(ExpirationMode.Sliding, TimeSpan.FromSeconds(10)));
FromConfiguration
takes either the CacheManagerConfiguration
object or a name
ed CacheManager configured in the app/web.config
file of the application.
var cache = CacheFactory.FromConfiguration<string>("cacheName")
Optionally, the name of the CacheManager instance and the name of the configured cache can be defined separated, to create multiple instances from the same configuration. The cache or cache handle name in general is optional. It can be used for debugging/logging purposes though.
var cache = CacheFactory.FromConfiguration<int>("cacheInstanceName", "configuredCacheName")
If you want to separate the creation of the configuration object and the creation of the Cache Manager instance, use the ConfigurationBuilder
to create the configuration.
var cfg = ConfigurationBuilder.BuildConfiguration(settings =>
{
settings.WithUpdateMode(CacheUpdateMode.Up)
.WithSystemRuntimeCacheHandle("handleName")
.WithExpiration(ExpirationMode.Sliding, TimeSpan.FromSeconds(10));
});
var cache = CacheFactory.FromConfiguration<string>("cacheName", cfg);
cache.Add("key", "value");
Then, you can reuse the configuration and create another Cache Manager instance for a different type for example:
var cache = CacheFactory.FromConfiguration<int>("numbers", cfg);
ConfigurationBuilderlink
The ConfigurationBuilder
has several static methods to initialize a CacheManagerConfiguration, to build a new one or load one from App.config
.
But it can also be instantiated to create new configurations or edit existing ones.
The same extension methods will be available as usual, the difference to the static method is, that you have to call Build
at some point to exit the configuration context and return the new configuration object.
var config = new ConfigurationBuilder()
.WithSystemRuntimeCacheHandle()
.EnableStatistics()
.Build();
// An existing configuration can be modified, too
var changedConfig = new ConfigurationBuilder(config)
.WithMicrosoftLogging(f => f.AddConsole())
.Build();
The CacheManagerConfiguration
also has a new property Builder
. Calling config.Builder
is the same as if you would call new ConfigurationBuilder(config)
.
var config = new ConfigurationBuilder()
.WithSystemRuntimeCacheHandle()
.EnableStatistics()
.Build();
// An existing configuration can be modified, too
var changedConfig = config
.Builder
.WithMicrosoftLogging(f => f.AddConsole())
.Build();
Instantiate BaseCacheManagerlink
Instead of using the CacheFactory
to create a cache instance, you can also create a new CacheManager instance by instantiating the BaseCacheManager
class directly and pass in a CacheManagerConfiguration
.
var config = new ConfigurationBuilder()
.WithSystemRuntimeCacheHandle()
.Build();
var cache = new BaseCacheManager<string>(config);
Microsoft.Extensions.Configurationlink
With the new Microsoft.Extensions.Configuration framework, Microsoft introduced a great way to handle custom configurations from many different sources, a plain JSON file for example.
JSON Schemalink
To making configuration via JSON files really easy, CacheManager now also has a JSON schema file, located at http://cachemanager.michaco.net/schemas/cachemanager.json.
With this schema, it is very easy and convenient if you create new configuration files in Visual Studio, because it gives full auto completion and validation on each element.
Just add a new JSON file to your project and add the "$schema" directive to it:
{
"$schema": "http://cachemanager.michaco.net/schemas/cachemanager.json#"
}
from there on, you should see validation messages in the error window of Visual Studio. First one will be Missing required property cacheManagers, which means that you have to have a cacheManagers
property of type array... and so on.
Here is a complete example:
{
"$schema": "http://cachemanager.michaco.net/schemas/cachemanager.json#",
"redis": [
{
"key": "redisConnection",
"connectionString": "localhost:6379,allowAdmin=true"
}
],
"cacheManagers": [
{
"maxRetries": 1000,
"name": "cachename",
"retryTimeout": 100,
"updateMode": "Full",
"backplane": {
"key": "redisConnection",
"knownType": "Redis",
"channelName": "test"
},
"loggerFactory": {
"knownType": "Microsoft"
},
"serializer": {
"knownType": "Json"
},
"handles": [
{
"knownType": "SystemRuntime",
"enablePerformanceCounters": true,
"enableStatistics": true,
"expirationMode": "Absolute",
"expirationTimeout": "0:0:23",
"isBackplaneSource": false,
"name": "sys cache"
},
{
"knownType": "Redis",
"key": "redisConnection",
"isBackplaneSource": true
}
]
}
]
}
Known Typeslink
As you might have noticed in the example above, there are a lot of knownType
properties. Known types are there to make configuration in text files easier and less error prone. Usually, you would have to declare the fully qualified type of a cache handle, logger factory or serializer.
With knownType
you can select from a predefined set of types which are known to CacheManager.
For example, instead of defining the type of a Redis cache handle and writing CacheManager.Redis.RedisCacheHandle`1, CacheManager.StackExchange.Redis
just define knownType: Redis
which gets evaluated to the full type name.
Hint: If you specify any type or knownType but didn't install the corresponding NuGet package which contains that type, you'll get an error at the point you instantiate a CacheManager.
Loading Configuration from JSON filelink
Loading a configuration via Microsoft's API works slightly different than the regular ConfigurationBuilder/Factory approach. You will have to build an IConfiguration
first, and then call the new extension method GetCacheConfiguration
to retrieve a CacheManagerConfiguration
.
First create the Microsoft.Extensions.Configuration.IConfiguration
var builder = new Microsoft.Extensions.Configuration.ConfigurationBuilder()
.AddJsonFile("cache.json");
this.Configuration = builder.Build();
and then call
var cacheConfiguration =
this.Configuration.GetCacheConfiguration();
The default overload without parameters assumes that there is only one CacheManagerConfiguration
defined in the cacheManagers
section of the JSON file.
If you have multiple managers defined, specify the name of the manager you want to load:
var cacheConfiguration =
this.Configuration.GetCacheConfiguration("cachename")
.Builder
.WithMicrosoftLogging(f =>
{
f.AddDebug(LogLevel.Information);
})
.Build();
You can also get all CacheManagerConfiguration
s by calling .GetCacheConfigurations()
.
Configuration Sectionlink
The CacheManager configuration section is only available in full .NET framework projects where System.Configuration.ConfigurationManager
is available.
The section has two main parts, the managers
collection which is used to configure one or more CacheManagers identified by name
(this name can be used in conjunction with CacheFactory.FromConfiguration
).
And the cacheHandles
collection which lists the available (installed) cache handle types. Those will be used by referencing (via ref
) the id
to form a cache in the managers
collection.
<cacheManager xmlns="http://cachemanager.michaco.net/schemas/CacheManagerCfg.xsd">
<managers>
<cache name="cacheName" updateMode="Up" enableStatistics="false" enablePerformanceCounters="false">
<handle name="handleName" ref="systemRuntimeHandle" expirationMode="Absolute" timeout="50s"/>
</cache>
</managers>
<cacheHandles>
<handleDef id="systemRuntimeHandle" type="CacheManager.SystemRuntimeCaching.MemoryCacheHandle`1, CacheManager.SystemRuntimeCaching"
defaultExpirationMode="Sliding" defaultTimeout="5m"/>
</cacheHandles>
</cacheManager>
The cacheHandles' elements can be defined with default values for expiration mode and timeout. It can be overridden by the handle
element though. The type
must a Type
extending from BaseCacheHandle
, it also has to be configured as open generic xyzHandle`1
at this point.
Hint To make configuration via .config file easier, enable intellisense by adding the
xmlns
attribute to hecacheManagers
section and add the CacheManagerCfg.xsd file to your solution. See also this answer on stackoverflow
The CacheManager and Redis configuration xml schema files can be found here: