Last Updated:

Implementing Unity Caching

When developing any high-load application, sooner or later the question of data caching arises. After all, almost always there is a part of the information that changes quite rarely and is used as a reference. Constantly requesting such information from the database is quite expensive, and by and large pointless.

There came a time when I, while developing such a high-load application, faced this problem. And solved it quite simply and painlessly with the help of Unity Application Block.

Initially, Unity in the project was used for its intended purpose, i.e. for dependency injection. But when the caching task arose, I remembered that Unity allows you to intercept method calls, which means that it is possible to implement the paradigm of aspect-oriented programming, which is perfect for this task.

Create an attribute

Let's create a special attribute with which we will mark the methods whose results will be stored in the application cache. Keep in mind that different data becomes obsolete at different rates, and for this purpose, the cache retention time is added to the attribute, after which this data is considered obsolete and is automatically deleted from the cache.

 

The attribute code is generally standard except for inheriting from the special HandlerAttribute class.

Next, we need to create the actual method call event interceptor. Here's his code.

 

As you can see, this attribute inherits from the ICallHandler interface and implements the Invoke method of this interface. Invoke is called just before the method itself is called.

Let's look at the Invoke method in more detail. First, the cache is checked for the presence in it of the result of the execution of the method with this name and these arguments and their values. If the value is found in the cache, it is returned from the cache. Otherwise, the execution of the method starts and the result is stored in the cache before exiting the procedure to be used when it is called again.

As you might have guessed, to use the cache, it is enough to mark the desired method with the [Cached] attribute and specify the time during which the data will be stored to the cache.

Cache itself

The following is just one of the possible cache implementations. Let me explain that in the example below, Hashtable is used as the main container, in which the key is the name of the method, and the value is another Hashtable, which in turn contains as a key a list of arguments and their values, and as a value - the result of the execution of these methods.

I did this for performance reasons, or rather the speed of searching for the container.

 

Below is a class that clears the cache and is also used to collect some statistics about its use. When it is created, a timer is triggered that deletes obsolete objects from the cache once a minute. When cleaning, first there is an attempt to access the container, and if this fails, the next cleaning is simply skipped.

 

That's really the solution. The article is quite long. In it, I showed how you can use the power of Unity to quickly and painlessly implement caching in your application, even if you did not think about it initially. The results of the implementation by the way exceeded the wildest expectations. The execution time of some methods, which were also called quite often and created a visible load on the database, was reduced hundreds of times.