When a request for a page (and similar for children listings) comes in to DataFactory the following occurs:
1. The page request is routed to the page provider serving the page.
2. The page is looked for in the cache and if exist there the page is returned (in this case the below steps are skipped).
3. The method GetLocalPage on the page provider is called.
4. The page is added to cache.
5. Page is returned.
So the method GetLocalPage (which is a requirement to implement for a page provider) is only called when a page is not found in cache.
If all handling of data served by a page provider (edit page, create page, delete page etc.) is done through EPiServer API, then you should not have to bother about caching of your provider pages. They will then be handled in the same way as the "local" EPiServer pages, which are added to cache with a sliding expiration (given by config setting pageCacheSlidingExpiration). The removal of cached pages is taken care of in event handlers hooked up for events such as SavedPage, DeletedPage etc.
If the data served by the page provider however can be manipulated outside EPiServer API (e.g. the data is stored in some other system that supports edit of data through some application) then you might want to control the caching of the pages. Here there are some options, depending on which type of latency that can be accepted.
Implement methods SetCacheSettings
There are two virtual methods SetCacheSettings in PageProviderBase that you can override to change the caching behavior of your pages. The methods contain a parameter of type CacheSettings which can be modified. If data is expected to be changed "outside" EPiServer API but you could accept a latency of e.g. 10 minutes then one alternative would be to set an AbsoluteExpiration for your pages as example below:
protected override void SetCacheSettings(PageData page, CacheSettings cacheSettings)
{
cacheSettings.AbsoluteExpiration = DateTime.Now.AddMinutes(10);
cacheSettings.SlidingExpiration = Cache.NoSlidingExpiration;
}
Another usages of overriding SetCacheSettings is to disable caching or add dependencies to other cached objects or some file (like XmlPageProvider does).
Call into DataFactoryCache
If you like to programmatically control page and/or listings removals from cache then you can call into DataFactoryCache. To programmatically remove a specific page and its children listing from cache you can call into DataFactoryCache like:
private void RemoveFromCache(PageReference pageLink)
{
DataFactoryCache.RemovePage(pageLink);
DataFactoryCache.RemoveListing(pageLink);
}
Each language version of a page is stored separately in cache meaning you can as an alternative remove only a specific language version of a page by calling DataFactoryCache.RemovePageLanguage(pageLink); (the method RemovePage will remove every language version of the page).
Remember though to pass in correct PageReference instances here, that is it should have RemoteSite value set if it references a page from a custom page provider. You can use helper method ConstructPageReference in PageProviderBase to construct the references.
You can also clear all pages/listings served from your page provider instance by calling method ClearProviderPagesFromCache() on the provider instance.
To be able to call into DataFactoryCache your code has to run "inside" EPiServer. So if you have code that runs in the other system you would need to call into EPiServer and run the cache removal code there. This could be achieved e.g. by exposing some WCF service on the EPiServer side.
Page dependency
If you have some custom object that you would like to store in cache and you want that object to have a dependency to some specific page then there are some methods/properties in DataFactoryCache that can help you.
- public static CacheDependency CreateDependency(PageReference pageLink) - Creates a CacheDependency to the specified page and its children listing.
- public static string PageCommonCacheKey(PageReference pageLink) - Gets the cache key that the specified page has, this is the cachekey that is common for all languages of the page.
- public static string PageLanguageCacheKey(PageReference pageLink, string languageBranch) - Gets the cache key for a page for a specific language.
- public static string ChildrenCacheKey(PageReference pageLink) - Get the cachekey for a children listing for a page.
So if you have an object instance that you want to add to the cache with a dependency to some specific page you would do something like:
object myObject = GetObject();
string cacheKey = GetUniqueCacheKey(myObject);
CacheDependency pageDependency = new CacheDependency(null, new string[1] { DataFactoryCache.PageCommonCacheKey(pageLink) });
CacheManager.RuntimeCacheInsert(cacheKey, myObject, pageDependency);
Ps.
There is actually a possibility to change the behavior for EPiServer local pages as well. You would in that case create a class that inherits EPiServer.LocalPageProvider and in that class override methods that you want to change behavior for e.g. SetCacheSettings (or GetLocalPage if you really want to mess up things :-) ). If you then register that page provider with name "default" then that class will be responsible for serving the "default" pages. Remember though that changing the "default" provider to something else than LocalPageProvider is nothing we support or recommend (it is a very central part of EPiServer and could cause many side affects) but it can be interesting to play around with.
Ds.