Caching

Caching allows you to increase the application’s performance.

In ELMA, there are three types of cache:

  • Global cache (ICacheService), used to write the data between web queries. Use it for caching data that doesn’t have to be up-to-date at this certain moment. If a server farm is used, the data stored in this cache is available and is the same for any ELMA server.
  • Server cache (IMemoryCacheService), used to store data in the memory of one ELMA server instance. Use it to write data that does not change during the server lifespan (for example, reflection data).
  • Context cache (IContextBoundVariableService), used to write data within one web-query. Use it to prevent any repeated calculations of data that does not affect the logic if updated within one web query.

Global Cache

ELMA has its own API for data caching, please do not use anything else, like ASP.NET Cache memcached etc.

The operation of this cache depends on the environment where the application is run. If it is run on one server, the data is stored in the server’s memory. In case of a server farm (cluster), it is stored in distributed cache (AppFabric cache service).

That is why you always have to consider the distributed cache when using this type of cache.

ICacheService

ICacheService is registered in the IoC container and is available for all server components of the application. The exact ICacheService execution depends on the environment where the application is run: an independent application on one IIS server, IIS based cluster farm or Windows Azure.

/// <summary>
/// Interface for operating cache
/// </summary>
public interface ICacheService
{
/// <summary>
/// Add or change cache item according to key, specifying dependency and caching time 
/// ATTENTION! This method might be deleted in the future since distributed cache does not support dependencies (windows appfabric cache, windows azure web cache etc.)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="dependencyKey"></param>
/// <param name="cacheDuration"></param>
void Insert<T>(string key, T value, string dependencyKey, TimeSpan cacheDuration);
 
/// <summary>
///  Add or change cache item according to key, specifying caching time 
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="cacheDuration"></param>
void Insert<T>(string key, T value, TimeSpan cacheDuration);
 
/// <summary>
///  Add or change cache item according to key with dependency
///  ATTENTION! This method might be deleted in the future since distributed cache does not support dependencies (windows appfabric cache, windows azure web cache and etc.)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="dependencyKey"></param>
void Insert<T>(string key, T value, string dependencyKey);
 
/// <summary>
///  Add or change cache item according to key
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
void Insert<T>(string key, T value);
 
/// <summary>
/// Check the item in cache according to key
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
bool Contains(string key);
 
/// <summary>
/// Get item from cache according to key
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
T Get<T>(string key);
 
/// <summary>
/// Delete item from cache according to key 
/// </summary>
/// <param name="key"></param>
void Remove(string key);
}

Caching method return values

The CacheAttribute attribute allows you to cache the return values of methods called from components. When the method is called, it composes a key based on the values of the sent arguments and uses ICacheService to check if the item is stored in cache. If it is, the value is returned from cache. If not, the method’s body is called, and the result is put into cache.

A method marked with the CacheAttribute attribute must comply with the following conditions: 

  • It is declared with the
  • virtual keyword
  • The return value can be serialized (marked with the Serializable attribute)
  • The method’s arguments must either be primitive or implement theIIdentified interface 

E.g., when loading data through URL, it is cached for 5 seconds:

using System.Net;
using System.Xml;
using EleWise.ELMA.Cache.Attributes;
using EleWise.ELMA.ComponentModel;
 
[Service] 
public class FeedLoader
{
 
/// <summary>
/// Load data in xml
/// </summary>
/// <param name="url">address</param>
/// <returns></returns> 
[Cache] 
public virtual XmlDocument Load(string url)
{
    var req = WebRequest.Create(url);
    var response = req.GetResponse();
    var stream = response.GetResponseStream();
    var xmlDocument = new XmlDocument();
    xmlDocument.Load(stream);
    return xmlDocument;
}
}

Context cache

ContextCacheAttribute allows you to cache the return values of the methods called from components during the lifespan of one HTTP request or other execution context.

Links to API elements

ICacheService