I need to activate second-level caching in EF Core that will cache the query result until the next time, instead of the database.
This is my CacheManager class
public class CacheManagerAdapter : ICacheService
{
private readonly YYYApi _api;
private ICacheManager<object> _cacheManager;
private static readonly string _cacheName;
static CacheManagerAdapter()
{
_cacheName = ConfigurationManager.AppSettings["cacheName"] ?? "CancelBookingCache";
}
public CacheManagerAdapter(IOptions<YYYApi> options)
{
_api = options.Value;
_cacheManager = CacheFactory.Build("cacheName", settings => settings
.WithUpdateMode(CacheUpdateMode.Up)
.WithRedisCacheHandle("redisCache")
.And.WithRedisConfiguration("redisCache", _api.cacheHost)
.WithJsonSerializer()
);
}
public void Clear()
{
_cacheManager.ClearRegion(_cacheName);
}
public bool Contains(string key)
{
return _cacheManager.GetCacheItem(key, _cacheName) == null;
}
public object Get(string key)
{
try
{
return _cacheManager.GetCacheItem(key, _cacheName).Value;
}
catch (Exception)
{
return null;
}
}
public T Get<T>(string key, Func<T> getItemCallback) where T : class
{
return _cacheManager.Get<T>(key, _cacheName);
}
public void Invalidate(Regex pattern)
{
throw new NotImplementedException();
}
public void Invalidate(string key)
{
_cacheManager.Remove(key, _cacheName);
}
public bool IsSet(string key)
{
throw new NotImplementedException();
}
public void Set(string key, object data, int cacheTime)
{
try
{
_cacheManager.AddOrUpdate(key, _cacheName, data, x => data);
if (cacheTime > 0)
{
_cacheManager.Expire(key, _cacheName, ExpirationMode.Absolute, new TimeSpan(0, cacheTime, 0));
}
}
catch (Exception ex)
{
}
}
}
the interface
public interface ICacheService
{
void Clear();
bool Contains(string key);
T Get<T>(string key, Func<T> getItemCallback) where T : class;
object Get(string key);
void Invalidate(string key);
void Invalidate(Regex pattern);
bool IsSet(string key);
void Set(string key, object data, int cacheTime);
}
So this is startup injection etc.
services.AddSingleton<ICacheService, CacheManagerAdapter>();
services.AddSingleton<IMMMAdapterService>(new MMMAdapterService(
XXX: new XXXController(
services.BuildServiceProvider().GetRequiredService<IOptions<YYYApi>>(),
_XXXLogger,
_diagnosticContext,
new CacheManagerAdapter(services.BuildServiceProvider().GetRequiredService<IOptions<YYYApi>>())
), _XXXLogger, _diagnosticContext));
services.AddSoapExceptionTransformer((ex) => ex.Message);
At the end, injection to controller
private readonly YYYApi _api;
readonly ILogger<XXXController> _logger;
readonly IDiagnosticContext _diagnosticContext;
readonly ICacheService _cache;
public XXXController(IOptions<YYYApi> options, ILogger<XXXController> logger, IDiagnosticContext diagnosticContext, ICacheService cache)
: base(options, logger)
{
_api = options.Value;
_logger = logger;
_diagnosticContext = diagnosticContext ?? throw new ArgumentNullException(nameof(diagnosticContext));
_cache = cache;
}
Depends on your project. You can cache data in multiple ways:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With