redcalx
redcalx

Reputation: 8637

Multiple instances of IDistributedCache?

IDistributedCache is provided as a standard API for accessing distributed caches from within ASP.NET applications. The provided API is very simple, basically presenting a cache as a container of key-value pairs, with DistributedCacheEntryOptions providing per-entry expiry options.

Now let's say within a single app there are lots of different types of data to be cached, some of which we may wish to logically group. Maybe we want some types of data to be grouped so we can e.g. choose to flush it all from the cache without affecting other types of data, or maybe we want the ability to put some types of data in a different cache cluster with high availability, or more resources for better performance, etc.

Given this I am leaning towards having a containing object that holds multiple instances of IDistributedCache, one each for a logical grouping. Given that this seems like it would be a common requirement I wonder if there is some standard way of achieving this pattern. Or maybe the advice would be to put everything into a single cache with a compound key (e.g. groupName-key), although I would prefer not do do that as I think it limits the flexibility of the caching layer.

As an aside I noticed that the NCache API provides the ability to optionally assign a groupName and subGroupName to each cache entry, which I think is pretty much what I want. However I would prefer to code against a IDistributedCache (or similar) in order to allow for drop-in alternative caching implementations.

Maybe another option is to create my own interface to provide the abstraction, but then I don't get the choice of using pre-built off-the-shelf IDistributedCache implementations (e.g. from NCache and Redis).

Also see: https://github.com/aspnet/Extensions/issues/2802

Upvotes: 5

Views: 4195

Answers (2)

Shoeb Lodhi
Shoeb Lodhi

Reputation: 156

Yes, I was also going to suggest that NCache Grouping Feature resolves your problem where you can assign groups to multiple items while adding them and then use Group APIs to manage these items as needed. Another solution could be through NCache Tags which are even more flexible in nature than groups and can be used to achieve the mentioned use case.

However, when using IDistributedCache interface, you are limited to cache calls that are supported with IDistributedCache interface. Although, NCache fully supports IDistributedCache interface but you still dont have option to use Groups or Tags. I will suggest below options for using Groups and Tags through IDistributedCache with NCache.

• Use NCache APIs directly along with NCache IDistributedCache interface. This will allow you to use additional functionality that NCache has and IDistributedCache interface lacks including Groups, Tags and other features. You will have to go outside IDistributedCache interface in this case to achieve the goal.

• Create your own custom extension methods for IDistributedCache and call NCache groups and Tag APIs in the extension method to achieve this. You will stay in your IDistributedCache implementation and will have additional functionality handled through your custom extension methods.

Upvotes: 1

Shaun Luttin
Shaun Luttin

Reputation: 141462

... within a single app there are lots of different types of data to be cached, some of which we may wish to logically group.

You could group your caches with wrapper interfaces like this:

public interface IDistributedCache01 : IDistributedCache { ... }
public interface IDistributedCache02 : IDistributedCache { ... }

Registration of those during startup would look something like this:

services.AddSingleton<IDistributedCache01, SqlServerCache>();
services.AddSingleton<IDistributedCache02, SqlServerCache>();

Then you can ask for specific caches in constructors:

public MyController(IDistributedCache01 cache)
{
    _cache = cache;
}

It's worth looking at the implementation of the built-in service registration methods. They are quite simple. Here they are for AddDistributedRedisCache and AddDistributedSqlServerCache.

When we take out the defensive programming, the registration methods are two lines of code:

services.AddSingleton<IDistributedCache, SqlServerCache>(); 
services.Configure(setupAction);

Upvotes: 2

Related Questions