Cache dependencies
Cache dependencies inform the system whenever the source data of a cached entity changes and prompt it to revoke the corresponding cache entry.
To create dependencies between cached data and its source, the system uses dummy cache keys. Dummy keys are cache items without any data that target objects or groups of objects. Each time an object is modified, the system touches all dummy keys that correspond to the object, which clears all cache items targeting at least one of the touched keys.
For example, assume an Articles page with the /Articles path in the content tree of a website channel News. On this page, there are short snippets of various articles, placed as the page’s children (/Articles/Best cities to live in, /Articles/New theme park in Georgia, etc.). As is good practice, all article snippets displayed on the page are cached.
Whenever any of the child pages change, the cache needs to be notified and revoke the cached article snippets – otherwise the Articles page continues displaying outdated content. To notify the cache, we introduce a dummy cache key dependency on the key webpageitem|bychannel|News|childrenofpath|/Articles
when caching the data. With this dependency, any change to child pages on the tree path /Articles under the channel News removes the corresponding cached article snippet from the cache, prompting the system to load fresh data from the database on a subsequent request.
The system provides the CacheDependencyBuilder
API that allows you to generate cache dependency keys from retrieved data (pages, content items, media files, etc.) and use them when caching data.
CacheDependencyBuilder API
CacheDependencyBuilder
provides fluent API for building cache dependencies from retrieved data. The API works with collections of system objects such as pages, content items, and info objects retrieved via content item query or database APIs and returns a CMSCacheDependency
object that plugs into IProgressiveCache.
Create the builder instance
Use ICacheDependencyBuilderFactory
to create instances of the CacheDependencyBuilder
class.
using CMS.Helpers;
public class MyClass
{
private readonly CacheDependencyBuilder cacheDependencyBuilder;
public MyClass(ICacheDependencyBuilderFactory cacheDependencyBuilderFactory)
{
cacheDependencyBuilder = cacheDependencyBuilderFactory.Create();
}
}
Build cache dependencies
The API allows you to construct cache dependencies via the following extension methods:
Extension method | Namespace | Description |
ForContentItems | CMS.ContentEngine | Creates cache dependencies on content items. See Create content item cache dependencies. |
ForWebPageItems | CMS.Websites | Creates cache dependencies on web page content types. See Create web page cache dependencies. |
ForInfoObjects | CMS.DataEngine | Creates cache dependencies on info object instances. See Create info object cache dependencies. |
ForSettingKeys | CMS.DataEngine | Creates cache dependencies on setting keys. See Create setting keys cache dependencies. |
ForMediaFiles | CMS.MediaLibrary | Creates cache dependencies on media files. See Create media file cache dependencies. |
AddDependency | CMS.Helpers | Not an extension method, available on the builder instance by default. Allows you to add a manually specified dependency to the set of constructed keys. See Reference – Cache dependency keys for an overview of supported cache dependencies and their required format. |
The final cache dependencies are created by calling Build
on the dependency builder instance after specifying all requirements. The method returns a CMSCacheDependency
instance that can be passed to IProgressiveCache
when caching data.
CMSCacheDependency dependency = cacheDependencyBuilder
// Specify all dependencies and call build
.Build();
Create content item cache dependencies
The ForContentItems
method allows you to create dependencies per individual content items, content types, or across all content items in the system.
// Creates a cache dependency on all content items in the system
CMSCacheDependency dependency = cacheDependencyBuilder
.ForContentItems()
.All()
.Builder()
.Build();
The preceding code example creates a dependency on all content items in the system, which means that the corresponding cache entry is removed every time any published content item in the system is modified.
CMSCacheDependency dependency = cacheDependencyBuilder
.ForContentItems()
// Creates a dependency on all items of the Coffee
// reusable content type using its corresponding generated class.
.ByContentType<Coffee>()
// To target only specific language variants, add the required
// language name to the method call.
.ByContentType<Coffee>("spanish")
.Builder()
.Build();
The preceding example targets all items of a specific reusable content type. Note that to target the content type, the example uses its corresponding generated class. The API offers additional overloads of the ByContentType
method that target the content type by its code name (with identical usage).
When targeting language variants, use the language code name as specified in the Languages application. To access the preferred language for the current request, you can use IPreferredLanguageRetriever.
// Assume a collection of content items on which to create the dependency
IEnumerable<Coffee> contentItems = GetContentItems();
CMSCacheDependency dependency = cacheDependencyBuilder
.ForContentItems()
// Creates a dependency using ID/GUID/CodeName
// of all items from the 'contentItems' collection
.ByGuid(contentItems)
.ById(contentItems)
.ByCodeName(contentItems)
.Builder()
.Build();
The preceding example creates a dependency on a specific collection of content items. Only by modifying one of the provided content items is the corresponding cache entry removed.
The ByGuid
, ById
, ByCodeName
methods can take either GUIDs, IDs, and CodeNames or collections of generated object classes. Treat the code example only as a preview of the available API. In real implementations, choose only one of these identifiers to create the cache dependency.
Create web page cache dependencies
The ForWebPageItems
method allows you to create dependencies per individual web page items, their content types, or across all web pages in the system.
// Creates a cache dependency on all web pages in the system
CMSCacheDependency dependency = cacheDependencyBuilder
.ForWebPageItems()
.All()
.Builder()
.Build();
The preceding code example creates a dependency on all web pages in the system, which means that the corresponding cache item is evicted every time any web page in the system is modified.
The All
method optionally allows a channelName
parameter that limits the created dependecy to all pages belonging to the specified website channel. To get the channel for the current context, you can use IWebsiteChannelContext.
CMSCacheDependency dependency = cacheDependencyBuilder
.ForWebPageItems()
// Creates a dependency on all pages of the 'CoffeeDetailPage'
// web page content type in the "mychannel" website channel
// using its generated class.
.ByContentType<CoffeeDetailPage>("mychannel")
// To target only specific language variants, add the required
// language name to the method call.
.ByContentType<CoffeeDetailPage>("mychannel", "spanish")
.Builder()
.Build();
The preceding example targets all web pages of a specific content type. Note that to target the content type, the example uses its generated class. The API offers additional overloads of the ByContentType
method that target the content type by its code name (with identical usage).
To get the channel for the current request, you can use IWebsiteChannelContext.
When targeting language variants, use the language code name as specified in the Languages application. To access the preferred language for the current request, you can use IPreferredLanguageRetriever.
// Assume a collection of web pages on which to create the dependency
IEnumerable<CoffeeDetailPage> webPages = GetDependencies();
CMSCacheDependency dependency = cacheDependencyBuilder
.ForWebPageItems()
// Creates a dependency using ID/GUID/CodeName
// of all items from the 'webPages' collection
.ByGuid(webPages)
.ById(webPages)
.ByCodeName(webPages)
.Builder()
.Build();
The preceding example creates a dependency on a specific collection of web pages. Only by modifying one of the provided web pages is the corresponding cache entry evicted.
The ByGuid
, ById
, ByCodeName
methods can take either GUIDs, IDs, and CodeNames or collections of generated object classes (for examples, see Retrieve page content). Treat the code example only as a preview of the available API. In real implementations, choose only one of these identifiers to create the cache dependency.
CoffeeDetailPage article = GetDependencies();
CMSCacheDependency dependency = cacheDependencyBuilder
.ForWebPageItems()
// Adds a dependency on the specific path
.ByPath(CacheDependencyPath.Single(article.SystemFields.WebPageItemTreePath), "mychannel")
// Adds dependencies on all children under the given path
.ByPath(CacheDependencyPath.Children(article.SystemFields.WebPageItemTreePath), "mychannel")
.Builder()
.Build();
The preceding example uses the position in the channel content tree to create cache dependencies. Whenever pages on the specified path are modified, the corresponding cache entry is removed.
Create info object cache dependencies
The ForInfoObjects<T>
method creates cache dependencies on info object instances of T
.
// Creates a dependency on all member accounts in the system
CMSCacheDependency cacheDependency = cacheDependencyBuilder
.ForInfoObjects<MemberInfo>()
.All()
.Builder()
.Build();
The preceding example creates a cache dependency on all MemberInfo objects in the system.
// Sample data containing the currently authenticated member account
MemberInfo currentMember = GetCurrentMember()
CMSCacheDependency cacheDependency = cacheDependencyBuilder
.ForInfoObjects<MemberInfo>()
.ById(currentMember.MemberID)
.Builder()
.Build();
The preceding example creates a dependency on the currently authenticated member account. To retrieve the currently authenticated member account, see Retrieve the currently authenticated member.
The ForInfoObjects
API allows creating dependencies using object:
- identifiers – the
ById
method - GUIDs – the
ByGuid
method - code names – the
ByCodeName
method
Create setting keys cache dependencies
The ForSettingKeys
method allows you to create dependencies on settings.
// Creates a cache dependency on system settings
CMSCacheDependency dependency = cacheDependencyBuilder
.ForSettingKeys()
.ByCodeName("CMSCIEnabled")
.Builder()
.Build();
The preceding example creates a dependency on the Continuous Integration setting.
ForSettingKeys
works only with default system settings. To create dependencies on custom settings, add a dependency on the custom info object representing your settings.
Create media file cache dependencies
The ForMediaFiles
method allows you to create dependencies on media library files.
// Sample media file on which to create the dependency
MediaFileInfo mediaFile = GetMediaFile();
// Creates a cache dependency on the provided media file
CMSCacheDependency dependency = cacheDependencyBuilder
.ForMediaFiles()
// Pass either a single GUID or a collection
.ByGuid(mediaFile.FileGUID)
.Builder()
.Build();
The preceding example creates a dependency on a media library file using its GUID. See Retrieve content from media libraries for an overview of the media library data retrieval API.
Specify additional dependencies
To add dependencies on other keys that cannot be created using CacheDependencyBuilder
APIs, use the AddDependency
method. A common scenario is including dependencies on linked items. See Cache dependencies on linked content items.
// Additional dependency keys, for example on linked items
// obtained from 'ILinkedItemsDependencyAsyncRetriever'
IEnumerable<string> linkedDependencies = GetLinkedDependencies();
CMSCacheDependency dependency = cacheDependencyBuilder
// Adds the keys from 'linkedDependencies' to the final result
.AddDependency(linkedDependencies)
.Build();
See the cache dependency key reference below for information about supported key constructions.
Reference – Cache dependency keys
The following sections list available dummy cache keys for objects in the system.
Avoid setting dependencies on all objects of a particular type via |all
. Clearing the cache every time any object of a given type changes has a high chance of significantly reducing the effectivness of your caching solution. Always prefer targeting specific objects either via code name or GUID.
Reusable content items
The following cache keys are touched when the Published version of the target reusable content item changes.
If you need to set cache dependencies for other workflow states, use the contentitem|allstates|*
prefix. Where *
can be substituted for any expression from the table that begins with contentitem
.
Dependency on | Cache key format | Description |
All items | contentitem|all Example:
| Targets all items in the system. |
ID | contentitem|byid|<ID> Example:
| Targets an item by its database ID and optionally language variant.
|
ID and language variant | contentitem|byid|<ID>|<languageName> Example:
| |
Code name | contentitem|byname|<codeName> Example:
| Targets an item by its code name and optionally language variant. Code names of content items can be found on the Properties tab when editing items in the Content hub application.
|
Code name and language variant | contentitem|byname|<codeName>|<languageName> Example:
| |
GUID | contentitem|byguid|<GUID> Example:
| Targets an item by its GUID and optionally language variant.
|
GUID and language variant | contentitem|<GUID>|<languageName> Example:
| |
Content type | contentitem|bycontenttype|<contentType> Example:
| Targets all items of the given content type and optionally language variant.
|
Content type and language variant | contentitem|bycontenttype|<contentType>|<languageName> Example:
|
Pages
The following cache keys are touched when the Published version of the target page changes.
If you need to set cache dependencies for other workflow states, use the webpageitem|allstates|*
prefix. Where *
can be substituted for any expression from the table, omitting the webpageitem
prefix. For example: webpageitem|allstates|all
.
Dependency on | Cache key format | Description |
All | webpageitem|all Example:
| Targets all pages in the system. |
All in website channel | webpageitem|bychannel|<channelName>|all Example:
| Targets all pages under the specified website channel. |
ID | webpageitem|byid|<ID> Example:
| Targets a page by it’s database ID and optionally language variant.
|
ID and language variant | webpageitem|byid|<ID>|<languageName> Example:
| |
Code name | webpageitem|byname|<codeName> Example:
| Targets a page by its code name and optionally language variant. The code name of a page can be found on the Properties tab when viewing pages under website channels.
|
Code name and language variant | webpageitem|byname|<codeName>|<languageName> Example:
| |
GUID | webpageitem|byguid|<GUID> Example:
| Targets an item by its GUID and optionally language variant.
|
GUID and language variant | webpageitem|byguid|<GUID>|<languageName> Example:
| |
Content type in website channel | webpageitem|bychannel|<channelName>|bycontenttype|<contentType> Example:
| Targets all pages of the specified content type and optionally language variant in the given channel.
|
Content type in website channel and language variant | webpageitem|bychannel|<channelName>|bycontenttype|<contentType>|<languageName> Example:
| |
Page path in website channel | webpageitem|bychannel|<channelName>|bypath|<pagePath> Example:
| Targets a page with the specified page path, channel, and optionally language variant.
Changing a page’s path touches both the old and the new |
Page path and language variant in website channel | webpageitem|bychannel|<channelName>|bypath|<pagePath>|<languageName> Example:
| |
Page path children in website channel | webpageitem|bychannel|<channelName>|childrenofpath|<pagePath> Example:
| Targets all children on all sublevels of the specified page path. Optionally targets only specified language variants.
|
Page path children of language variant in website channel | webpageitem|bychannel|<channelName>|childrenofpath|<pagePath>|<languageName> Example:
|
Media files
Dependency on | Cache key format | Example | Description |
GUID | mediafile|<guid> | mediafile|1ced44f3-f2fc- … | Cache dependencies can only target media library files using their GUID. |
Settings
Dependency on | Cache key format | Description |
Code name | cms.settingskey|byname|<settingCodeName> | Targets the settings specified by the given code name. |
General objects
Dependency on | Cache key format | Example | Description |
All | <object type>|all | cms.user|all | Targets all administration users in the system. |
ID | <object type>|byid|<id> | cms.user|byid|53 | Targets the administration user with the specific ID. |
Code name | <object type>|byname|<code name> | cms.user|byname|administrator | Targets the administration user with the specific code name. |
GUID | <object type>|byguid|<guid> | cms.user|byguid|1ced44f3-f2fc- … | Targets the administration user with the specific GUID. |
Form data records
The system currently does not touch any dummy cache keys when changes occur for data submitted via forms.
As a workaround, developers can prepare custom event handlers for BizFormItemEvents
. Use the handler method to touch a custom cache key, and then enter the key into your cache dependencies. For example:
private void FormItem_InsertAfterHandler(object sender, BizFormItemEventArgs e)
{
// Touches a custom cache key, for example: "customformdata|bizform.contactus"
CacheHelper.TouchKey("customformdata|" + e.Item.BizFormClassName);
}