Created
April 14, 2021 19:43
-
-
Save csharpforevermore/705cf8b45ed588bce0358831711f7c4b to your computer and use it in GitHub Desktop.
MVC Core cache example - create one per entity and use DI to inject
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Threading.Tasks; | |
using Microsoft.Extensions.Caching.Memory; | |
using Microsoft.Extensions.Logging; | |
using Paige.Caching.BaseCache; | |
using Paige.ModelLayer.Enums; | |
using Paige.ModelLayer.Interfaces.Cache; | |
using Paige.ModelLayer.Interfaces.Config; | |
using Paige.ModelLayer.Interfaces.Entity; | |
using Paige.ModelLayer.Models.Entity; | |
namespace Paige.Caching.Caches | |
{ | |
public class EntityCache : ICache<IList<EntityModel>> | |
{ | |
private readonly IEntityManager _EntityManager; | |
private readonly Cache _Cache; | |
private readonly ILogger _Logger; | |
private readonly IApplicationConfigManager _ApplicationConfigManager; | |
private const string CACHE_TIME_INTERVAL = "EntityCacheTimeInterval"; | |
private const string CACHE_LENGTH = "EntityCacheLength"; | |
public EntityCache(IEntityManager EntityManager, Cache cache, ILogger<EntityCache> logger, | |
IApplicationConfigManager applicationConfigManager) | |
{ | |
_EntityManager = EntityManager; | |
_Cache = cache; | |
_Logger = logger; | |
_ApplicationConfigManager = applicationConfigManager; | |
_Logger.LogInformation("Entity Cache constructor called."); | |
} | |
private IList<EntityModel> _TempCache; | |
public string CacheName => "EntityCache"; | |
public async void CacheExpires(object key, object value, EvictionReason reason, object state) | |
{ | |
_TempCache = (IList<EntityModel>)value; | |
//Only want to regenerate if it expires. | |
if (reason == EvictionReason.Expired || reason == EvictionReason.Removed || | |
reason == EvictionReason.TokenExpired) | |
{ | |
await CreateCache(); | |
} | |
//Reset it | |
_TempCache = null; | |
} | |
public async Task CreateCache() | |
{ | |
//Default to use if it fails | |
var expiry = _Cache.GetExpiryTime(TimeInterval.Second, 20); | |
try | |
{ | |
var data = await _EntityManager.GetAllEntitys(); | |
if (data != null) | |
{ | |
var cacheInterval = _ApplicationConfigManager.GetConfigValue<TimeInterval>(CACHE_TIME_INTERVAL); | |
int length = _ApplicationConfigManager.GetConfigValue<int>(CACHE_LENGTH); | |
expiry = _Cache.GetExpiryTime(cacheInterval, length); | |
_Cache.CreateCache(CacheName, data, expiry, CacheExpires); | |
} | |
else | |
{ | |
//Try again in 20 seconds as there should be some data | |
_Cache.CreateCache<IList<EntityModel>>(CacheName, null, expiry, CacheExpires); | |
} | |
} | |
catch (Exception e) | |
{ | |
_Logger.LogError(e, $"Failed to create cache for {CacheName}"); | |
//If we have failed, then lets try again in 20 seconds. | |
_Cache.CreateCache<IList<EntityModel>>(CacheName, null, expiry, CacheExpires); | |
} | |
} | |
public IList<EntityModel> RetrieveDataFromCache() | |
{ | |
//Give the temp cache while the new one is being regenerated. | |
return _TempCache ?? _Cache.GetCache<IList<EntityModel>>(CacheName); | |
} | |
public void RemoveCache() | |
{ | |
//This will trigger the recache because there is the removed EvictionReason in CacheExpired. | |
_Cache.RemoveCache(CacheName); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment