Pavalisoft.Caching  1.2.1
A single unified Caching Api for both MemoryCache and DistributedCache implementations including CacheManager
Pavalisoft.Caching Documentation

Caching

Pavalisoft.Caching is an open source caching extension for .NET Standard written in C#, which provides single unified API for both MemoryCache and DistributedCache implementations.

The main goal of the Pavalisoft.Caching package is to make developer's life easier to handle even very complex caching scenarios and concentrate on functionality. It's additional feature CacheManager supports various cache providers and implements many advanced features which can be used in single project/application.

With Pavalisoft.Caching, it is possible to implement multiple layers of caching with multiple cache providers in one place, e.g. MemoryCache and DistributedCache, in just a few lines of code.

The below diagram explains the Pavalisoft.Caching API and its usage.

Documentation & Samples

Complete Documentation is available at https://pavalisoft.github.io/Caching/ for Pavalisoft.Caching API

Refer https://github.com/pavalisoft/Caching/tree/master/Samples for reference implementations

Cache Manager Usage

  1. Define the Cache Stores and Partitions in Caching configuration section in appSettings.json.
{
  "Caching": {
    "Stores": [
      {
        "Name": "InMemory",
        "Type": "Pavalisoft.Caching.InMemory.InMemoryCacheStoreType, Pavalisoft.Caching.InMemory",
        "StoreConfig": "{\"ExpirationScanFrequency\":\"00:05:00\"}"
      },
      {
        "Name": "DistributedInMemory",
        "Type": "Pavalisoft.Caching.InMemory.MemoryDistributedCacheStoreType,Pavalisoft.Caching.InMemory",
        "SerializerType": "Pavalisoft.Caching.Serializers.JsonSerializer,Pavalisoft.Caching",
        "StoreConfig": "{\"ExpirationScanFrequency\":\"00:05:00\"}"
      },
      {
        "Name": "SqlServer",
        "Type": "Pavalisoft.Caching.SqlServer.SqlServerDistributedCacheStoreType,Pavalisoft.Caching.SqlServer",
        "SerializerType": "Pavalisoft.Caching.Serializers.JsonSerializer,Pavalisoft.Caching",
        "StoreConfig": "{\"ExpiredItemsDeletionInterval\":\"00:05:00\", \"ConnectionString\":\"Data Source=localhost;Initial Catalog=DistributedCache;Integrated Security=True\", \"SchemaName\":\"store\", \"TableName\":\"Cache\", \"DefaultSlidingExpiration\":\"00:05:00\"}"
      },
      {
        "Name": "MySql",
        "Type": "Pavalisoft.Caching.MySql.MySqlDistributedCacheStoreType,Pavalisoft.Caching.MySql",
        "SerializerType": "Pavalisoft.Caching.Serializers.JsonSerializer,Pavalisoft.Caching",
        "StoreConfig": "{\"ExpiredItemsDeletionInterval\":\"00:05:00\", \"ConnectionString\":\"Data Source=localhost;User Id=root;Password=root;Allow User Variables=true\", \"SchemaName\":\"store\", \"TableName\":\"Cache\", \"DefaultSlidingExpiration\":\"00:05:00\"}"
      },
      {
        "Name": "Redis",
        "Type": "Pavalisoft.Caching.Redis.RedisDistributedCacheStoreType,Pavalisoft.Caching.Redis",
        "SerializerType": "Pavalisoft.Caching.Serializers.JsonSerializer,Pavalisoft.Caching",
        "StoreConfig": "{\"Configuration\":\"00:05:00\", \"InstanceName\":\"localhost\"}"
      }
    ],
    "Partitions": [
      {
        "Name": "FrequentData",
        "StoreName": "InMemory",
        "SlidingExpiration": "00:05:00"
      },
      {
        "Name": "DistributedFrequentData",
        "StoreName": "DistributedInMemory",
        "SlidingExpiration": "00:05:00"
      },
      {
        "Name": "MySqlLocalizationData",
        "StoreName": "MySql",
        "Priority": "NeverRemove"
      },
      {
        "Name": "LocalizationData",
        "StoreName": "SqlServer",
        "Priority": "NeverRemove"
      },
      {
        "Name": "MasterData",
        "StoreName": "Redis",
        "SlidingExpiration": "00:05:00"
      }
    ]
  }
}
  1. Add Pavalisoft.Caching to services. Also add the Pavalisoft.Caching.InMemory , Pavalisoft.Caching.MySql , Pavalisoft.Caching.Redis and Pavalisoft.Caching.SqlServer Cache store implementations to services based on usage.
...
//Import the below namespace to use InMemory and DistributedInMemory cache store implementations
using Pavalisoft.Caching.InMemory;
//Import the below namespace to use MySql cache store implementation
using Pavalisoft.Caching.MySql;
//Import the below namespace to use Redis Cache Store implementation
using Pavalisoft.Caching.Redis;
//Import the below namespace to use SqlServer Cache Store implementation
using Pavalisoft.Caching.SqlServer;
...

namespace Pavalisoft.Caching.Sample
{
    public class Startup
    {
		...
        public Startup(IConfiguration configuration)
        {
			...
            Configuration = configuration;
			...
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            ...
            // Adds CacheManager service to services
            services.AddCaching()
                // Adds InMemory and Distributed InMemory Cache Store implementations to CacheManager
                .AddInMemoryCache()
                // Adds MySql Cache Store implementations to CacheManager
                .AddMySqlCache()
                // Adds Redis Cache Store implementations to CacheManager
                .AddRedisCache()
                // Adds SqlServer Cache Store implementations to CacheManager
                .AddSqlServerCache();
			...
        }
		...
    }
}
  1. Use AddCaching(CacheSettings cacheSettings) extension method to pass the CacheSettings instead of json in appsettings.json file
...
//Import the below namespace to use InMemory and DistributedInMemory cache store implementations
using Pavalisoft.Caching.InMemory;
//Import the below namespace to use MySql cache store implementation
using Pavalisoft.Caching.MySql;
//Import the below namespace to use Redis Cache Store implementation
using Pavalisoft.Caching.Redis;
//Import the below namespace to use SqlServer Cache Store implementation
using Pavalisoft.Caching.SqlServer;
...

namespace Pavalisoft.Caching.Sample
{
    public class Startup
    {
		...
        public Startup(IConfiguration configuration)
        {
			...
            Configuration = configuration;
			...
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            ...
            // Adds CacheManager service to services
            services.AddCaching(CreateCacheSettings())
                // Adds InMemory and Distributed InMemory Cache Store implementations to CacheManager
                .AddInMemoryCache()
                // Adds MySql Cache Store implementations to CacheManager
                .AddMySqlCache()
                // Adds Redis Cache Store implementations to CacheManager
                .AddRedisCache()
                // Adds SqlServer Cache Store implementations to CacheManager
                .AddSqlServerCache();
			...
        }
        private static CacheSettings CreateCacheSettings()
        {
            return new CacheSettings
            {
                Stores = new List<CacheStoreDefinition>
                {
                    new CacheStoreDefinition
                    {
                        Name = "InMemory",
                        Type = typeof(InMemoryCacheStoreType).AssemblyQualifiedName,
                        StoreConfig = JsonConvert.SerializeObject( new MemoryCacheOptions
                        {
                            ExpirationScanFrequency = new TimeSpan(0,5,0)
                        })
                    },
                    new CacheStoreDefinition
                    {
                        Name = "DistributedInMemory",
                        Type = typeof(MemoryDistributedCacheStoreType).AssemblyQualifiedName,
                        SerializerType = typeof(Serializers.JsonSerializer).AssemblyQualifiedName,
                        StoreConfig = JsonConvert.SerializeObject( new MemoryDistributedCacheOptions
                        {
                            ExpirationScanFrequency = new TimeSpan(0,5,0)
                        })
                    }
                },
                Partitions = new List<CachePartitionDefinition>
                {
                    new CachePartitionDefinition
                    {
                        Name = "FrequentData",
                        StoreName = "InMemory",
                        SlidingExpiration = new TimeSpan(0,5,0)
                    },
                    new CachePartitionDefinition
                    {
                        Name = "DistributedFrequentData",
                        StoreName = "DistributedInMemory",
                        SlidingExpiration = new TimeSpan(0,5,0)
                    }
                }
            };
        }
		...
    }
}
  1. Use CacheManager methods to add, get, refresh and remove items in Cache.
// Add required using statements
using Pavalisoft.Caching;
using Pavalisoft.Caching.Interfaces;
using Microsoft.Extensions.Primitives;
using System;

namespace Pavalisoft.Caching.Sample
{
	public class CachingSample
	{
		private const string CachePartitionName = "FrequentData";		
		private readonly ICacheManager _cacheManager;
		public CachingSample(ICacheManager cacheManager)
		{
			_cacheManager = cacheManager;
		}

		public AppUser GetAppUser(HttpContext httpContext)
		{
			var userName = httpContext.User.Identity.Name;
			AppUser appUser;
			
			// Try to get the appUser from cache
			if (!_cacheManager.TryGetValue(CachePartitionName, userName, out appUser))
			{
				// If not available in Cache then create new instance of AppUser
				appUser = new AppUser(userName);

				// Add appUser object to Cache
				_cacheManager.Set(CachePartitionName, userName, appUser);                `
			}
			return appUser;
		}
	}
}

Cache Tag Helper Usage

  1. Define the Cache Stores and Partitions in Caching configuration section in appSettings.json.
{
  "Caching": {
    "Stores": [
      {
        "Name": "InMemory",
        "Type": "Pavalisoft.Caching.InMemory.InMemoryCacheStoreType, Pavalisoft.Caching.InMemory",
        "StoreConfig": "{\"ExpirationScanFrequency\":\"00:05:00\"}"
      },
      {
        "Name": "DistributedInMemory",
        "Type": "Pavalisoft.Caching.InMemory.MemoryDistributedCacheStoreType,Pavalisoft.Caching.InMemory",
        "SerializerType": "Pavalisoft.Caching.Serializers.JsonSerializer,Pavalisoft.Caching",
        "StoreConfig": "{\"ExpirationScanFrequency\":\"00:05:00\"}"
      },
      {
        "Name": "SqlServer",
        "Type": "Pavalisoft.Caching.SqlServer.SqlServerDistributedCacheStoreType,Pavalisoft.Caching.SqlServer",
        "SerializerType": "Pavalisoft.Caching.Serializers.JsonSerializer,Pavalisoft.Caching",
        "StoreConfig": "{\"ExpiredItemsDeletionInterval\":\"00:05:00\", \"ConnectionString\":\"Data Source=localhost;Initial Catalog=DistributedCache;Integrated Security=True\", \"SchemaName\":\"store\", \"TableName\":\"Cache\", \"DefaultSlidingExpiration\":\"00:05:00\"}"
      },
      {
        "Name": "MySql",
        "Type": "Pavalisoft.Caching.MySql.MySqlDistributedCacheStoreType,Pavalisoft.Caching.MySql",
        "SerializerType": "Pavalisoft.Caching.Serializers.JsonSerializer,Pavalisoft.Caching",
        "StoreConfig": "{\"ExpiredItemsDeletionInterval\":\"00:05:00\", \"ConnectionString\":\"Data Source=localhost;User Id=root;Password=root;Allow User Variables=true\", \"SchemaName\":\"store\", \"TableName\":\"Cache\", \"DefaultSlidingExpiration\":\"00:05:00\"}"
      },
      {
        "Name": "Redis",
        "Type": "Pavalisoft.Caching.Redis.RedisDistributedCacheStoreType,Pavalisoft.Caching.Redis",
        "SerializerType": "Pavalisoft.Caching.Serializers.JsonSerializer,Pavalisoft.Caching",
        "StoreConfig": "{\"Configuration\":\"00:05:00\", \"InstanceName\":\"localhost\"}"
      }
    ],
    "Partitions": [
      {
        "Name": "FrequentData",
        "StoreName": "InMemory",
        "SlidingExpiration": "00:05:00"
      },
      {
        "Name": "DistributedFrequentData",
        "StoreName": "DistributedInMemory",
        "SlidingExpiration": "00:05:00"
      },
      {
        "Name": "MySqlLocalizationData",
        "StoreName": "MySql",
        "Priority": "NeverRemove"
      },
      {
        "Name": "LocalizationData",
        "StoreName": "SqlServer",
        "Priority": "NeverRemove"
      },
      {
        "Name": "MasterData",
        "StoreName": "Redis",
        "SlidingExpiration": "00:05:00"
      }
    ]
  }
}
  1. Add Pavalisoft.Caching to services. Also add the Pavalisoft.Caching.InMemory , Pavalisoft.Caching.MySql , Pavalisoft.Caching.Redis and Pavalisoft.Caching.SqlServer Cache store implementations to services based on usage.
...
//Import the below namespace to use InMemory and DistributedInMemory cache store implementations
using Pavalisoft.Caching.InMemory;
//Import the below namespace to use MySql cache store implementation
using Pavalisoft.Caching.MySql;
//Import the below namespace to use Redis Cache Store implementation
using Pavalisoft.Caching.Redis;
//Import the below namespace to use SqlServer Cache Store implementation
using Pavalisoft.Caching.SqlServer;
...

namespace Pavalisoft.Caching.Sample
{
    public class Startup
    {
		...
        public Startup(IConfiguration configuration)
        {
			...
            Configuration = configuration;
			...
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            ...
            // Adds CacheManager service to services
            services.AddCaching()
                // Adds InMemory and Distributed InMemory Cache Store implementations to CacheManager
                .AddInMemoryCache()
                // Adds MySql Cache Store implementations to CacheManager
                .AddMySqlCache()
                // Adds Redis Cache Store implementations to CacheManager
                .AddRedisCache()
                // Adds SqlServer Cache Store implementations to CacheManager
                .AddSqlServerCache();
			...
        }
		...
    }
}
  1. Use AddCaching(CacheSettings cacheSettings) extension method to pass the CacheSettings instead of json in appsettings.json file
...
//Import the below namespace to use InMemory and DistributedInMemory cache store implementations
using Pavalisoft.Caching.InMemory;
//Import the below namespace to use MySql cache store implementation
using Pavalisoft.Caching.MySql;
//Import the below namespace to use Redis Cache Store implementation
using Pavalisoft.Caching.Redis;
//Import the below namespace to use SqlServer Cache Store implementation
using Pavalisoft.Caching.SqlServer;
...

namespace Pavalisoft.Caching.Sample
{
    public class Startup
    {
		...
        public Startup(IConfiguration configuration)
        {
			...
            Configuration = configuration;
			...
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            ...
            // Adds CacheManager service to services
            services.AddCaching(CreateCacheSettings())
                // Adds InMemory and Distributed InMemory Cache Store implementations to CacheManager
                .AddInMemoryCache()
                // Adds MySql Cache Store implementations to CacheManager
                .AddMySqlCache()
                // Adds Redis Cache Store implementations to CacheManager
                .AddRedisCache()
                // Adds SqlServer Cache Store implementations to CacheManager
                .AddSqlServerCache();
			...
        }
        private static CacheSettings CreateCacheSettings()
        {
            return new CacheSettings
            {
                Stores = new List<CacheStoreDefinition>
                {
                    new CacheStoreDefinition
                    {
                        Name = "InMemory",
                        Type = typeof(InMemoryCacheStoreType).AssemblyQualifiedName,
                        StoreConfig = JsonConvert.SerializeObject( new MemoryCacheOptions
                        {
                            ExpirationScanFrequency = new TimeSpan(0,5,0)
                        })
                    },
                    new CacheStoreDefinition
                    {
                        Name = "DistributedInMemory",
                        Type = typeof(MemoryDistributedCacheStoreType).AssemblyQualifiedName,
                        SerializerType = typeof(Serializers.JsonSerializer).AssemblyQualifiedName,
                        StoreConfig = JsonConvert.SerializeObject( new MemoryDistributedCacheOptions
                        {
                            ExpirationScanFrequency = new TimeSpan(0,5,0)
                        })
                    }
                },
                Partitions = new List<CachePartitionDefinition>
                {
                    new CachePartitionDefinition
                    {
                        Name = "FrequentData",
                        StoreName = "InMemory",
                        SlidingExpiration = new TimeSpan(0,5,0)
                    },
                    new CachePartitionDefinition
                    {
                        Name = "DistributedFrequentData",
                        StoreName = "DistributedInMemory",
                        SlidingExpiration = new TimeSpan(0,5,0)
                    }
                }
            };
        }
		...
    }
}
  1. To use pavalisoft-cache tag helper, add the below to _ViewImport.cshtml
@addTagHelper *, Pavalisoft.Caching.TagHelpers
  1. Use the pavalisoft-cache tag helper in the view wherever required.
<div class="col-md-12">
    <h2>Pavalisoft Cache TagHelper</h2>
    <div class="row">
        <pavalisoft-cache cache-partition="FrequentData">
            This will be cached in server memory. expires-after 05 minutes
        </pavalisoft-cache>
    </div>
    <div class="row">
        <pavalisoft-cache cache-partition="DistributedFrequentData">
            This will be cached in server distributed memory. expires-sliding (05 minutes)
        </pavalisoft-cache>
    </div>
    <div class="row">
        <pavalisoft-cache cache-partition="MySqlLocalizationData">
            This will be cached in MySQL distributed memory. expires-after 05 minutes
        </pavalisoft-cache>
    </div>
    <div class="row">
        <pavalisoft-cache cache-partition="LocalizationData">
            This will be cached in Sql Server distributed memory. expires-after 05 minutes
        </pavalisoft-cache>
    </div>
    <div class="row">
        <pavalisoft-cache cache-partition="MasterData">
            This will be cached in Redis distributed memory. expires-sliding (05 minutes)
        </pavalisoft-cache>
    </div>
</div>

Cache Store Configurations

The below classes are used for providing the StoreConfig to the respective CacheStores.

Serializers

Below are the list of serializers options available, which can be used to serialize and deserialize object from and to Distributed Cache Stores.

  • BinaryFormatter - Requires the classes decorated with SerializableAttribute to store into Distributed Cache Stores.
  • Newtonsoft.Json - Uses Newtonsoft.Json to serialize a class without SerializableAttribute.

Builds

Get latest builds from nuget

Package Version
Pavalisoft.Caching 1.2.1
Pavalisoft.Caching.TagHelpers 1.0.0
Pavalisoft.Caching.InMemory 1.0.0
Pavalisoft.Caching.Redis 1.0.0
Pavalisoft.Caching.MySql 1.0.0
Pavalisoft.Caching.SqlServer 1.0.0

Contributing

Getting started with Git and GitHub

Once you're familiar with Git and GitHub, clone the repository and start contributing.