An efficient multi-layered caching system for .NET
Microsoft.Extensions.Logging.Abstractions
. If you don't have logging configured, it will internally default to the built-in NullLogger
. This was done as part of the serialization changes to stop exceptions crashing out during caching but as a way they are still logged.CacheStack
in favour of using a constructor which takes a CacheStackOptions
ICacheRefreshCallSiteWrapperExtension
with IDistributedLockExtension
, a simplified alternative to handling distributed lockingRedisLockExtension
for distributed lockingBesides the removal of some obsolete extension methods on service collections, the rest of these changes shouldn't affect the most common scenario of using Cache Tower via Dependency Injection.
Full Changelog: https://github.com/TurnerSoftware/CacheTower/compare/0.13.0...0.14.0
This is mainly an internal implementation change as CacheEntry
was publicly passed around as CacheEntry<T>
which is still there with the same constructor and properties. If you were using CacheEntry
somewhere, you'll likely be able to switch it out for ICacheEntry
instead. The change is being explicitly called out in case any subtle behaviour changes occur because of it.
The dependency injection improvements are around passing in an IServiceProvider
into the builder pattern and supporting named cache stacks. This makes it easier to configure your cache stacks for the code that consumes them.
There are a number of breaking changes in this release of Cache Tower. For the most part, these APIs will be marked as "obsolete" and should still behave as they did previously however it is important to recognise the changes that have occurred to understand the breadth of incompatibility.
Rather than restricting cache layers to specific serializers, you can now supply custom serializers to cache layers that require it. Officially, Cache Tower will support 3 serializers: Newtonsoft.Json, System.Text.Json and Protobuf (via protobuf-net).
RedisCacheLayer
currently takes a dependency on CacheTower.Serializers.Protobuf
for backwards compatibility for 0.12.0
and will be changed in a future release. There is a new constructor that ICacheSerializer
allowing you to specify any serializer you want. The transitive dependency on CacheTower.Serializers.Protobuf
will be removed in a future version.JsonFileCacheLayer
and ProtobufFileCacheLayer
are now obsolete, instead use FileCacheLayer
and specify an ICacheSerializer
to use.Additional changes to note:
JsonFileCacheLayer
used to specifically serialize your data wrapped in its own JSON object (eg. {"value": _ }
) which it no longer does. Due to the file extension change, this shouldn't cause a problem as your cache will be empty. Through additional unit tests, this doesn't seem to cause a problem however if you hit an issue where it does, please raise an issue.One problem that has been raised a few times are issues around the manifest files for caching. The manifest was only writing down to the file system when the application gracefully exited. Manifests now save automatically in the background and the interval is controllable via options on the FileCacheLayer
.
Additionally, there were two other fixes:
FileMode
access to force truncation of data when serializing (this may have been causing specific types of cache entry corruption)The fluent dependency injection process simplifies configuring Cache Tower and will be recommended method going forward. There are some minor API breaking changes when you upgrade, even if you don't use the fluent API around how certain cache layers and extensions are configured.
There are some underlying changes to how the RedisRemoteEvictionExtension
works - you no longer can specify which cache layers to evict from. Cache layers are now decorated with ILocalCacheLayer
and IDistributedCacheLayer
which the extension uses to identify what cache layers it will evict from. Specifically, no distributed cache layer will be evicted from by the extension.
Changes to RedisLockExtension
have occurred around how you specify certain options, specifically around specifying a LockCheckStrategy
to choose between a pub/sub or spin lock strategy.