Caching your objects on the server - marcos8154/SocketAppServer GitHub Wiki
The framework allows you to store your objects in a Self Managed Cache to optimize data retrieval speed. To do this, we will use the CacheRepository class, located in the MobileAppServer.ServerObjects namespace.
Let's exemplify using Action GetProductsByCategory in our test project.
public ActionResult GetProductsByCategory(Guid categoryId)
{
ProductRepository repository = new ProductRepository();
List<Product> productsByCategory = repository.GetProducts(categoryId);
return ActionResult.Json(productsByCategory);
}
We want to return a Product list from the Category Id. In a trivial and obvious way, we receive the category Id as a parameter and submit it to any repository (usually database), in order to get the list of products and return the request.
The problem is that we often return little (or almost never) volatile data. And that can be costly and repetitive for the repository. In these cases we can make responses faster by returning data from the cache instead of the repository.
First, we will define a "key" so that Cache can identify the data. This key could be the common data composition that contains part of the data we want to identify, as in the example below.
string key = $"productsByCategory-{categoryId.ToString()}";
With the key set, we can search the Cache repository, which will return us with a Cache object:
Cache<List<Product>> cached = CacheRepository<List<Product>>.Get(key);
If the Cache object is not null, we can immediately return the value of the "Value" property as a result of the request.
Cache<List<Product>> cached = CacheRepository<List<Product>>.Get(key);
if (cached != null)
return ActionResult.Json(cached.Value);
If Cache is null, then yes, we will go to our product repository and make the query in the normal way. After retrieving the query data from the product data repository, we need to store this result in Cache, given the key along with the data and an expiration time:
ProductRepository repository = new ProductRepository();
List<Product> productsByCategory = repository.GetProducts(categoryId);
CacheRepository<List<Product>>.Set(key, productsByCategory, 180);
See how our complete Action looks after Cache implementation:
public ActionResult GetProductsByCategory(Guid categoryId)
{
string key = $"productsByCategory-{categoryId.ToString()}";
Cache<List<Product>> cached = CacheRepository<List<Product>>.Get(key);
if (cached != null)
return ActionResult.Json(cached.Value);
ProductRepository repository = new ProductRepository();
List<Product> productsByCategory = repository.GetProducts(categoryId);
CacheRepository<List<Product>>.Set(key, productsByCategory, 180);
return ActionResult.Json(productsByCategory);
}
In addition to the ways of use shown above, there are some interesting parameters to be informed when adding data to Cache:
//Set method in CacheRepostory<T>
public static void Set(string key, T entity, int time, bool eternal = false, string[] methodsToInvokeOnExpire = null);
- key (string): key for data identification
- entity (T): object instance in which to store
- time (int): time (in seconds) that the entry will remain alive in cache
- eternal (bool): determines if data will be forever in the cache
- methodsToInvokeOnExpire (string []): Method names in the cached object. These methods will be invoked as the object is about to be destroyed from the cache.